#if (FEATURE_MODE == 0)
/**
 @file sys_usw_npm.c

 @date 2014-10-28

 @version v3.0


*/

/****************************************************************
 *
 * Header Files
 *
 ***************************************************************/
#include "ctc_error.h"
#include "ctc_npm.h"
#include "ctc_packet.h"
#include "ctc_oam.h"
#include "ctc_qos.h"

#include "sys_usw_common.h"
#include "sys_usw_npm.h"
#include "sys_usw_nexthop_api.h"
#include "sys_usw_dmps.h"
#include "sys_usw_qos_api.h"
#include "sys_usw_oam_db.h"
#include "sys_usw_register.h"
#include "sys_usw_dma.h"
#include "sys_usw_interrupt.h"
#include "sys_usw_acl_api.h"
#include "sys_usw_stats_api.h"

#include "drv_api.h"
/****************************************************************************
 *
* Defines and Macros
*
*****************************************************************************/
#define SYS_USW_MAX_LEN_SESSION_MODE_8           96
#define SYS_USW_MAX_LEN_SESSION_MODE_6           128
#define SYS_USW_MAX_LEN_SESSION_MODE_4           192
#define SYS_USW_MAX_LEN_SESSION_MODE_32          192
#define SYS_USW_MAX_LEN_SESSION_MODE_16          384

#define SYS_NPM_UINT64_MAX      0xFFFFFFFFFFFFFFFFLLU
#define SYS_NPM_MAX_PRIORITY       15

#define SYS_NPM_MIN_TOTAL_PACKET_SIZE 64
#define SYS_NPM_LOOP_WITH_TIMESTAMP_INFO   6
#define SYS_NPM_MAX_LOST_RATE              100
#define SYS_NPM_TX_INTERVAL_TO_PPS           1000
/****************************************************************************
*
* Global and Declaration
*
*****************************************************************************/
sys_npm_master_t* g_npm_master[CTC_MAX_LOCAL_CHIP_NUM_PP] = {NULL};
extern int32 sys_usw_nh_init_twamp_rsv_nh(uint8 lchip);

extern int32 sys_usw_npm_im_set_flow_en(uint8 lchip, uint32 type, uint32 enable);
extern int32 sys_usw_npm_im_wb_init(uint8 lchip);
extern int32 sys_usw_npm_im_wb_sync(uint8 lchip, uint32 app_id);
extern int32 sys_usw_npm_im_wb_restore(uint8 lchip);
extern int32 sys_usw_npm_im_init(uint8 lchip, ctc_npm_global_cfg_t* p_npm_global_cfg);
extern int32 sys_usw_npm_im_deinit(uint8 lchip);
/****************************************************************************
 *
 * Function
 *
 *****************************************************************************/

#define __INTERNAL_FUNC__

STATIC sys_npm_session_t *
_sys_usw_npm_lkup_session(uint8 lchip, uint32 session_id)
{
    sys_npm_session_t * npm_session = NULL;
    npm_session = (sys_npm_session_t*)ctc_vector_get(g_npm_master[lchip]->session, session_id);
    return npm_session;
}

STATIC int32
_sys_usw_npm_parameter_check(uint8 lchip, ctc_npm_cfg_t* p_cfg)
{
    ctc_port_if_mode_t if_mode;
    uint32 cmd = 0;
    uint8 mode = 0;
    uint8 max_session = 0;
    uint8 index = 0;
    uint8 sub_index = 0;
    AutoGenPktGlbCtl_m glb_ctl;
    ctc_npm_pkt_format_t* p_pkt_format = NULL;
    uint32 value = 0;
    uint32 tmp_value = 0;
    uint32 field_id = 0;
    uint8 is_match = 0;
    uint32 speed_mode = 0;
    uint32 max_speed = 0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};

    SYS_NPM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    p_pkt_format = &(p_cfg->pkt_format);

    SYS_NPM_DBG_OUT(CTC_DEBUG_LEVEL_INFO,
       "lchip:%d, session_id:%u, rate:%u, pkt_num:%u, pkt_len:%u \n",
        lchip, p_cfg->session_id, p_cfg->rate, p_cfg->packet_num, p_pkt_format->frame_size);
    SYS_NPM_DBG_OUT(CTC_DEBUG_LEVEL_INFO,
       "tx_mode:%d, tx_period:%u, burst_cnt:%u, ibg:%u, timeout:%d(s) \n",
        p_cfg->tx_mode, p_cfg->tx_period, p_cfg->burst_cnt, p_cfg->ibg, p_cfg->timeout);
    SYS_NPM_DBG_OUT(CTC_DEBUG_LEVEL_INFO,
       "size_mode:%d, min_size:%u, flag:0x%x \n",
        p_pkt_format->frame_size_mode, p_pkt_format->min_frame_size, p_cfg->flag);

    CTC_MAX_VALUE_CHECK(p_cfg->tx_mode, (CTC_NPM_TX_MODE_MAX-1));
    CTC_MAX_VALUE_CHECK(p_cfg->pkt_format.color, CTC_QOS_COLOR_GREEN);
    CTC_MAX_VALUE_CHECK(p_cfg->pkt_format.priority, SYS_NPM_MAX_PRIORITY);
    CTC_MAX_VALUE_CHECK(p_cfg->dm_stats_mode, (CTC_NPM_MAX_MEASURE_MODE-1));
    CTC_MAX_VALUE_CHECK(p_cfg->vrf_id, MCHIP_CAP(SYS_CAP_SPEC_MAX_VRFID));
    CTC_MAX_VALUE_CHECK(p_cfg->flr_for_ses, SYS_NPM_MAX_LOST_RATE);

    if (p_cfg->vlan_id)
    {
        CTC_VLAN_RANGE_CHECK(p_cfg->vlan_id);
    }

    if (!p_cfg->rate)
    {
        return CTC_E_INVALID_PARAM;
    }

    if ((!CTC_FLAG_ISSET(p_cfg->flag, CTC_NPM_CFG_FLAG_MCAST)) && (!CTC_IS_LINKAGG_PORT(p_cfg->dest_gport)))
    {
        dmps_port_info.gport = p_cfg->dest_gport;
        CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_SPEED_MODE, &speed_mode));
        switch (speed_mode)
        {
            case CTC_PORT_SPEED_10M:
                max_speed = 10000;
                break;
            case CTC_PORT_SPEED_100M:
                max_speed = 100000;
                break;
            case CTC_PORT_SPEED_1G:
                max_speed = 1000000;
                break;
            case CTC_PORT_SPEED_2G5:
                max_speed = 2500000;
                break;
            case CTC_PORT_SPEED_5G:
                max_speed = 5000000;
                break;
            case CTC_PORT_SPEED_10G:
                max_speed = 10000000;
                break;
            case CTC_PORT_SPEED_20G:
                max_speed = 20000000;
                break;
            case CTC_PORT_SPEED_25G:
                max_speed = 25000000;
                break;
            case CTC_PORT_SPEED_40G:
                max_speed = 40000000;
                break;
            case CTC_PORT_SPEED_50G:
                max_speed = 50000000;
                break;
            case CTC_PORT_SPEED_100G:
                max_speed = 100000000;
                break;
            case CTC_PORT_SPEED_200G:
                max_speed = (DRV_FROM_AT(lchip)? 200000000 : 100000000);
                break;
            case CTC_PORT_SPEED_400G:
            case CTC_PORT_SPEED_800G:
                max_speed = (DRV_FROM_AT(lchip)? 300000000 : 100000000);
                break;            
            
            default:
                max_speed = 1000000;
                break;
        }
#ifdef EMULATION_ENV
         max_speed = 2000000000;
#endif
        sys_usw_port_api_get_interface_mode(lchip,p_cfg->dest_gport,&if_mode);

        /* kbps, can not exceed speed of dest port */
        if ((max_speed) && (p_cfg->rate > max_speed) && (if_mode.interface_type != CTC_PORT_IF_FLEXE))
        {
            SYS_NPM_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Invalid rate, exceed port max rate \n");
            return CTC_E_INVALID_PARAM;
        }
        /*Tx 99.9% capbility of max_speed*/
        p_cfg->rate = (p_cfg->rate > ((uint64)max_speed * 999 / 1000)) ? ((uint64)max_speed * 999 / 1000) : p_cfg->rate;
    }

    if ((!p_pkt_format->ipg) || (p_pkt_format->ipg > SYS_IPG_MAX_VALUE))
    {
        SYS_NPM_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Invalid IPG value \n");
        return CTC_E_INVALID_PARAM;
    }

    if ((p_cfg->tx_mode == CTC_NPM_TX_MODE_PACKET_NUM) && (!p_cfg->packet_num))
    {
        return CTC_E_INVALID_PARAM;
    }

    if ((p_cfg->tx_mode == CTC_NPM_TX_MODE_PERIOD) && (!p_cfg->tx_period))
    {
        return CTC_E_INVALID_PARAM;
    }

    if (CTC_FLAG_ISSET(p_cfg->flag, CTC_NPM_CFG_FLAG_BURST_EN) && (!p_cfg->burst_cnt))
    {
        return CTC_E_INVALID_PARAM;
    }
    CTC_MAX_VALUE_CHECK(p_cfg->oam_type,CTC_OAM_TYPE_TRILL_BFD_ECHO);
    CTC_MAX_VALUE_CHECK(p_pkt_format->pattern_type, (CTC_NPM_PATTERN_TYPE_MAX-1));
    CTC_MAX_VALUE_CHECK(p_pkt_format->frame_size_mode, 2);
    CTC_PTR_VALID_CHECK(p_pkt_format->pkt_header);

    cmd = DRV_IOR(AutoGenPktGlbCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &glb_ctl));
    mode = GetAutoGenPktGlbCtl(V, sessionMode_f, &glb_ctl);
    if (!p_pkt_format->header_len
    || ((((mode == CTC_NPM_SESSION_MODE_8) && p_pkt_format->header_len > (SYS_USW_MAX_LEN_SESSION_MODE_8 - SYS_USW_PKT_HEADER_LEN))
    || ((mode == CTC_NPM_SESSION_MODE_6) && p_pkt_format->header_len > (SYS_USW_MAX_LEN_SESSION_MODE_6 - SYS_USW_PKT_HEADER_LEN))
    || ((mode == CTC_NPM_SESSION_MODE_4) && p_pkt_format->header_len > (SYS_USW_MAX_LEN_SESSION_MODE_4 - SYS_USW_PKT_HEADER_LEN)))
    &&(!DRV_FROM_TMM(lchip)))
    ||((((mode == CTC_NPM_SESSION_MODE_32) && p_pkt_format->header_len > (SYS_USW_MAX_LEN_SESSION_MODE_32 - SYS_USW_PKT_HEADER_LEN))
    || ((mode == CTC_NPM_SESSION_MODE_16) && p_pkt_format->header_len > (SYS_USW_MAX_LEN_SESSION_MODE_16 - SYS_USW_PKT_HEADER_LEN)))
    &&(DRV_FROM_TMM(lchip))))
    {
        return CTC_E_INVALID_PARAM;
    }

    if ((CTC_FLAG_ISSET(p_cfg->flag, CTC_NPM_CFG_FLAG_SEQ_EN)) &&
         ((p_pkt_format->seq_num_offset < 14) || (p_pkt_format->seq_num_offset > p_pkt_format->header_len - 4)))
    {
        return CTC_E_INVALID_PARAM;
    }
    if ((CTC_FLAG_ISSET(p_cfg->flag, CTC_NPM_CFG_FLAG_TS_EN)) &&
         ((p_pkt_format->ts_offset < 14) || (p_pkt_format->ts_offset > p_pkt_format->header_len - 8)
         || (1 ==(p_pkt_format->ts_offset % 2)) || (p_pkt_format->ts_offset > MCHIP_CAP(SYS_CAP_NPM_MAX_TS_OFFSET))))
    {
        return CTC_E_INVALID_PARAM;
    }

    /*Increase mode*/
    if (p_pkt_format->frame_size_mode == 1)
    {
        if ((p_pkt_format->min_frame_size < SYS_NPM_MIN_TOTAL_PACKET_SIZE) || (p_pkt_format->min_frame_size < (p_pkt_format->header_len+4)))
        {
            return CTC_E_INVALID_PARAM;
        }

        if ((p_pkt_format->frame_size < SYS_NPM_MIN_TOTAL_PACKET_SIZE) || (p_pkt_format->frame_size < (p_pkt_format->header_len+4)))
        {
            return CTC_E_INVALID_PARAM;
        }

        if (p_pkt_format->min_frame_size > p_pkt_format->frame_size)
        {
            return CTC_E_INVALID_PARAM;
        }

        CTC_MAX_VALUE_CHECK(p_pkt_format->frame_size, MCHIP_CAP(SYS_CAP_PORT_MAX_FRAMESIZE_MAX_VALUE));
        CTC_MAX_VALUE_CHECK(p_pkt_format->min_frame_size, MCHIP_CAP(SYS_CAP_PORT_MAX_FRAMESIZE_MAX_VALUE));
    }
    else if (p_pkt_format->frame_size_mode == 2)
    {
        /*Emix mode*/
        if (!p_pkt_format->emix_size_num)
        {
            return CTC_E_INVALID_PARAM;
        }

        CTC_MAX_VALUE_CHECK(p_pkt_format->emix_size_num, CTC_NPM_MAX_EMIX_NUM);

        for (index = 0; index < p_pkt_format->emix_size_num; index++)
        {
            is_match = 0;
            value = p_pkt_format->emix_size[index];
            if ((value < SYS_NPM_MIN_TOTAL_PACKET_SIZE) || (value < (p_pkt_format->header_len+4)))
            {
                return CTC_E_INVALID_PARAM;
            }

            CTC_MAX_VALUE_CHECK(value, MCHIP_CAP(SYS_CAP_PORT_MAX_FRAMESIZE_MAX_VALUE));

            for (sub_index = 0; sub_index < CTC_NPM_MAX_EMIX_NUM; sub_index++)
            {
                field_id = AutoGenPktGlbCtl_g_0_size_f + sub_index;
                drv_get_field(lchip, AutoGenPktGlbCtl_t, field_id, &glb_ctl, &tmp_value);
                if (value == tmp_value)
                {
                    is_match = 1;
                    break;
                }
            }

            if (!is_match)
            {
                return CTC_E_INVALID_PARAM;
            }

        }
    }
    else
    {
        /*Fix mode*/
        if ((p_pkt_format->frame_size < SYS_NPM_MIN_TOTAL_PACKET_SIZE) || (p_pkt_format->frame_size < (p_pkt_format->header_len+4)))
        {
            return CTC_E_INVALID_PARAM;
        }

        CTC_MAX_VALUE_CHECK(p_pkt_format->frame_size, MCHIP_CAP(SYS_CAP_PORT_MAX_FRAMESIZE_MAX_VALUE));
    }

    if ((!DRV_FROM_TMM(lchip))&&p_cfg->dm_stats_mode > 2)
    {
        return CTC_E_INVALID_PARAM;
    }
    max_session = DRV_FROM_TMM(lchip)?(mode?16:32):((mode)?((mode == 1)?6:4):8);
    SYS_NPM_MAX_SESSION_CHECK(max_session, p_cfg->session_id);

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_npm_set_bridge_hdr(uint8 lchip, ctc_npm_cfg_t* p_cfg,  MsPacketHeader_m* p_hdr)
{
    uint8  gchip = 0;
    uint16 lport = 0;
    uint32 p_nhid;
    uint32 dest_map = 0;
    uint32 nexthop_ptr = 0;
    int32 ret = CTC_E_NONE;
    uint32 bheader[64/4] = {0}; /*hdr+tail*/
	//uint8 bridge_hdr[64] = {0}; /*hdr + tail*/
	MsPacketHeader_m* p_bridge_hdr =NULL;
    uint8 pkt_hdr_len =0;
    uint32 nh_offset = 0;

    SYS_NPM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    p_bridge_hdr = (MsPacketHeader_m*)(bheader + (DRV_FROM_TMM(lchip)? SYS_USW_PKT_HDR_TAIL_LEN/4 : 0) + (DRV_FROM_AT(lchip)? SYS_USW_PKT_HDR_XBUS_LEN/4 : 0));
    if (!CTC_FLAG_ISSET(p_cfg->flag, CTC_NPM_CFG_FLAG_MCAST))
    {
        if(!CTC_IS_LINKAGG_PORT(p_cfg->dest_gport) && !CTC_FLAG_ISSET(p_cfg->flag, CTC_NPM_CFG_FLAG_NHID_VALID))
        {
            SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(p_cfg->dest_gport, lchip, lport);
            gchip = SYS_MAP_CTC_GPORT_TO_GCHIP(p_cfg->dest_gport);
        }
    }
    else
    {
        if (CTC_E_NOT_EXIST == sys_usw_nh_get_mcast_nh(lchip, p_cfg->dest_gport, &p_nhid))
        {
            return CTC_E_INVALID_PARAM;
        }
    }
    if (CTC_FLAG_ISSET(p_cfg->flag, CTC_NPM_CFG_FLAG_ILOOP))
    {
        if (CTC_IS_LINKAGG_PORT(p_cfg->dest_gport)
            ||(CTC_FLAG_ISSET(p_cfg->flag, CTC_NPM_CFG_FLAG_MCAST)))
        {
            return CTC_E_INVALID_PARAM;
        }
        if (!DRV_FROM_TMM(lchip))
        {
            SetPacketHeader(V, destMap_f, p_bridge_hdr, SYS_ENCODE_DESTMAP(gchip, SYS_RSV_PORT_ILOOP_ID));
        }
        SetPacketHeader(V, nextHopPtr_f, p_bridge_hdr, SYS_NH_ENCODE_ILOOP_DSNH(lport,0,0,0,0));
        if (CTC_FLAG_ISSET(p_cfg->flag, CTC_NPM_CFG_FLAG_VRF_EN))
        {
            /* bits 0-13 is vrf id bit 14 is vrf enable */
            SetPacketHeader(V, u1_oam_rxFcb_f, p_bridge_hdr, (p_cfg->vrf_id | (1<<14)));
        }
    }
    else if (CTC_FLAG_ISSET(p_cfg->flag, CTC_NPM_CFG_FLAG_NHID_VALID))
    {
        sys_nh_info_dsnh_t nh_info;
        uint32 gport = 0;
        sal_memset(&nh_info, 0, sizeof(sys_nh_info_dsnh_t));
        CTC_ERROR_RETURN(sys_usw_nh_get_nhinfo(lchip, p_cfg->nh_id, &nh_info, 0));
        dest_map = nh_info.dest_map;
        nexthop_ptr = nh_info.dsnh_offset;
        if(nh_info.aps_en)
        {
            CTC_ERROR_RETURN(sys_usw_nh_get_aps_working_path(lchip, p_cfg->nh_id, &gport, &nexthop_ptr, NULL));
            dest_map = SYS_ENCODE_DESTMAP(SYS_MAP_CTC_GPORT_TO_GCHIP(gport), SYS_MAP_CTC_GPORT_TO_DRV_LPORT(gport));
        }
        SetPacketHeader(V, destMap_f, p_bridge_hdr, dest_map);
        SetPacketHeader(V, nextHopExt_f, p_bridge_hdr, nh_info.nexthop_ext);
        SetPacketHeader(V, nextHopPtr_f, p_bridge_hdr, nexthop_ptr);
        SetPacketHeader(V, bypassIngressEdit_f, p_bridge_hdr, nh_info.bypass_igr_edit);
    }
    else
    {
        /* get bypass nexthop */
        ret = sys_usw_nh_get_resolved_offset(lchip, SYS_NH_RES_OFFSET_TYPE_BYPASS_NH, &nexthop_ptr);
        if (CTC_FLAG_ISSET(p_cfg->flag, CTC_NPM_CFG_FLAG_MCAST))
        {
            SetPacketHeader(V, destMap_f, p_bridge_hdr, SYS_ENCODE_MCAST_IPE_DESTMAP(p_cfg->dest_gport));
            SetPacketHeader(V, nextHopPtr_f, p_bridge_hdr, 0);
        }
        else if(CTC_FLAG_ISSET(p_cfg->flag, CTC_NPM_CFG_FLAG_TS_EN))
        {
            dest_map = (CTC_IS_LINKAGG_PORT(p_cfg->dest_gport))?
                SYS_ENCODE_DESTMAP(CTC_LINKAGG_CHIPID, p_cfg->dest_gport&0xFF): SYS_ENCODE_DESTMAP(gchip, lport);
            CTC_ERROR_RETURN(sys_usw_nh_get_resolved_offset(lchip, SYS_NH_RES_OFFSET_TYPE_TWAMP_CHKSUM_NH, &nh_offset));
            SetPacketHeader(V, destMap_f, p_bridge_hdr, dest_map);
            SetPacketHeader(V, nextHopPtr_f, p_bridge_hdr, nh_offset);
            SetPacketHeader(V, nextHopExt_f , p_bridge_hdr, 0);
        }
        else
        {
            dest_map = (CTC_IS_LINKAGG_PORT(p_cfg->dest_gport))?
                SYS_ENCODE_DESTMAP(CTC_LINKAGG_CHIPID,  SYS_MAP_CTC_GPORT_TO_DRV_LPORT(p_cfg->dest_gport)): SYS_ENCODE_DESTMAP(gchip, lport);
            SetPacketHeader(V, destMap_f, p_bridge_hdr, dest_map);
            SetPacketHeader(V, nextHopPtr_f, p_bridge_hdr, nexthop_ptr);
            SetPacketHeader(V, nextHopExt_f , p_bridge_hdr, 1);
        }
    }
    if (DRV_FROM_TMM(lchip)&& !CTC_FLAG_ISSET(p_cfg->flag, CTC_NPM_CFG_FLAG_ILOOP))
    {
        SetPacketHeader(V, bypassIpe_f, p_bridge_hdr, 0x1);
    }
    SetPacketHeader(V, ttl_f, p_bridge_hdr, 255);
    SetPacketHeader(V, srcVlanPtr_f, p_bridge_hdr, p_cfg->vlan_id);
    SetPacketHeader(V, outerVlanIsCVlan_f, p_bridge_hdr, (p_cfg->vlan_domain)?1:0);
    SetPacketHeader(V, sourcePort_f , p_bridge_hdr, SYS_RSV_PORT_OAM_CPU_ID);
    if (CTC_FLAG_ISSET(p_cfg->flag, CTC_NPM_CFG_COLOR))
    {
        SetPacketHeader(V, color_f , p_bridge_hdr, p_cfg->pkt_format.color);
    }
    else
    {
        SetPacketHeader(V, color_f , p_bridge_hdr, CTC_QOS_COLOR_GREEN);
    }
    if (CTC_FLAG_ISSET(p_cfg->flag, CTC_NPM_CFG_PRIORITY))
    {
        SetPacketHeader(V, prio_f , p_bridge_hdr, p_cfg->pkt_format.priority);
    }
    else
    {
        SetPacketHeader(V, prio_f , p_bridge_hdr, 0);
    }
    SetPacketHeader(V, fromCpuOrOam_f, p_bridge_hdr, 1);
    SetPacketHeader(V, operationType_f , p_bridge_hdr, 7);
    SetPacketHeader(V, u1_oam_oamType_f , p_bridge_hdr, p_cfg->oam_type);

    if (CTC_FLAG_ISSET(p_cfg->flag, CTC_NPM_CFG_FLAG_TS_EN))
    {
        SetPacketHeader(V, u1_oam_dmEn_f, p_bridge_hdr, TRUE);
        if (DRV_FROM_TMM(lchip))
        {
            /* mep index bit 6 indicate after loop add timestamp at mac */
            SetPacketHeader(V, u1_oam_mepIndex_f, p_bridge_hdr, 1<<SYS_NPM_LOOP_WITH_TIMESTAMP_INFO);
            SetPacketHeader(V, u1_oam_rxtxFclLOrDmOffset_f, p_bridge_hdr, p_cfg->pkt_format.ts_offset);
            if (p_cfg->nh_id)
            {
                ret = sys_usw_nh_set_ts_edit_en(lchip, p_cfg->nh_id, TRUE);
                if (CTC_E_NONE == ret)
                {
                    /* mep index bit 6 indicate after loop add timestamp at mac */
                    SetPacketHeader(V, u1_oam_mepIndex_f, p_bridge_hdr, 0<<SYS_NPM_LOOP_WITH_TIMESTAMP_INFO);
                }
            }
        }
        else
        {
            SetPacketHeader(V, u1_dmtx_dmOffset_f, p_bridge_hdr, p_cfg->pkt_format.ts_offset);
        }
        if (CTC_FLAG_ISSET(p_cfg->flag, CTC_NPM_CFG_FLAG_TUNNEL_PKT))
        {
            SetPacketHeader(V, u1_oam_isTunnelDmTx_f, p_bridge_hdr, 1);
        }
    }
    if (CTC_FLAG_ISSET(p_cfg->flag, CTC_NPM_CFG_FLAG_NTP_TS))
    {
        SetPacketHeader(V, u1_oam_twampTsType_f, p_bridge_hdr, TRUE);
    }

    pkt_hdr_len = SYS_USW_PKT_HEADER_LEN - (DRV_FROM_TMM(lchip)? SYS_USW_PKT_HDR_TAIL_LEN : 0) - (DRV_FROM_AT(lchip)? SYS_USW_PKT_HDR_XBUS_LEN : 0) ;
#if 0
    for (i = 0; i < pkt_hdr_len/4; i++)
    {
        bridge_hdr[i*4 + 0] = ((uint8*)p_bridge_hdr)[i*4 + 3];
        bridge_hdr[i*4 + 1] = ((uint8*)p_bridge_hdr)[i*4 + 2];
        bridge_hdr[i*4 + 2] = ((uint8*)p_bridge_hdr)[i*4 + 1];
        bridge_hdr[i*4 + 3] = ((uint8*)p_bridge_hdr)[i*4 + 0];
    }
    sal_memcpy((uint8*)p_bridge_hdr, bridge_hdr,  pkt_hdr_len);
    for (i = 0; i < (pkt_hdr_len / 4); i++)
    {
        ((uint32 *)bridge_hdr)[i] = DRV_SWAP32(((uint32 *)p_bridge_hdr)[i]);
    }
    sys_usw_byte_reverse_copy((uint8*)p_bridge_hdr, bridge_hdr, pkt_hdr_len);
    //sys_usw_dword_reverse_copy((uint32 *)p_bridge_hdr, (uint32 *)bridge_hdr, SYS_USW_PKT_HEADER_LEN/4);
#else

    pkt_hdr_len = SYS_USW_PKT_HEADER_LEN;
    sys_usw_dword_reverse_copy((uint32*)p_hdr, (uint32*)bheader, pkt_hdr_len / 4);
    sys_usw_swap32((uint32*)p_hdr, pkt_hdr_len / 4, FALSE);

#endif
    return ret;
}

STATIC int32
_sys_usw_npm_set_user_data(uint8 lchip, ctc_npm_cfg_t* p_cfg, void* p_pkt_header)
{
    uint32 cmd = 0;
    uint32 up_ptr = 0;
    AutoGenPktPktHdr_m ds_pkt_hdr;
    AutoGenPktGlbCtl_m glb_ctl;
    uint32* p_hdr = NULL;
    uint8* p_tmp_hdr = NULL;
    uint8 index = 0;
    uint8 session_id = 0;
    uint8 session_mode = 0;
    uint16 header_len = 0;
    uint8 remnant = 0;
    uint32 step =0;
   uint32 pkthdr_index = 0;
   uint32 value=0;
   uint8 max_array =0;
   uint32 last_word = 0;

    SYS_NPM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    session_id = p_cfg->session_id;
    cmd = DRV_IOR(AutoGenPktGlbCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &glb_ctl));
    session_mode = GetAutoGenPktGlbCtl(V, sessionMode_f, &glb_ctl);
    switch (session_mode)
    {
        case CTC_NPM_SESSION_MODE_8:
            up_ptr = DRV_FROM_AT(lchip)?((session_id<<1)+session_id):((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip))? (session_id << 2) : ((session_id << 4) - (session_id << 2)));
            break;
        case CTC_NPM_SESSION_MODE_6:
            up_ptr = DRV_FROM_AT(lchip)?((session_id<<2)+(session_id<<1)):(DRV_FROM_TMM(lchip)? (session_id << 3) :(session_id << 4));
            break;
        case CTC_NPM_SESSION_MODE_4:
             up_ptr = ((session_id << 5) - (session_id << 3));
             break;
         default:
             break;
    }
    sal_memset(&ds_pkt_hdr, 0, sizeof(AutoGenPktPktHdr_m));

    /* config one section */
    p_hdr = (uint32*)p_pkt_header;
    header_len = p_cfg->pkt_format.header_len + SYS_USW_PKT_HEADER_LEN;
    if (DRV_FROM_TMM(lchip))
    {
        uint8 one_tbl_len = (DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip))? 12 : 16;
        step = AutoGenPktPktHdr_array_1_pktHdrUserdata_f - AutoGenPktPktHdr_array_0_pktHdrUserdata_f;
        for (index = 0; index < header_len / (one_tbl_len*4); index++)
        {
            for (pkthdr_index = 0; pkthdr_index < one_tbl_len; pkthdr_index++)
            {
                value = DRV_SWAP32(p_hdr[index*one_tbl_len + pkthdr_index]);
                cmd = DRV_IOW(AutoGenPktPktHdr_t, AutoGenPktPktHdr_array_0_pktHdrUserdata_f + step *(one_tbl_len - 1 - pkthdr_index));
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, (up_ptr + index), cmd, &value));
            }
        }
        remnant = header_len % (one_tbl_len*4);
        if (remnant)
        {
            index = header_len / (one_tbl_len*4);
            if (remnant % 4)
            {
                p_tmp_hdr = (uint8*)p_pkt_header;
                max_array = remnant / 4 + 1;
                if (1 == remnant%4)
                {
                    last_word = p_tmp_hdr[index * (one_tbl_len*4) + (remnant / 4) *4];
                }
                else if (2 == remnant%4)
                {
                    last_word = (p_tmp_hdr[index * (one_tbl_len*4) + (remnant / 4) *4 ]) + (p_tmp_hdr[index * (one_tbl_len*4) + (remnant / 4) *4 + 1] << 8);
                }
                else if (3 == remnant%4)
                {
                    last_word = (p_tmp_hdr[index * (one_tbl_len*4) + (remnant / 4) *4]) + (p_tmp_hdr[index * (one_tbl_len*4) + (remnant / 4) *4 + 1] << 8) + 
                              (p_tmp_hdr[index * (one_tbl_len*4) + (remnant / 4) * 4 + 2] << 16);
                }
            }
            else
            {
                max_array = remnant / 4 ;
            }
            for (pkthdr_index = 0; pkthdr_index < max_array; pkthdr_index++)
            {
                value = (remnant%4? ((max_array-1 == pkthdr_index)? DRV_SWAP32(last_word): DRV_SWAP32(p_hdr[index*one_tbl_len + pkthdr_index]))
                        : DRV_SWAP32(p_hdr[index*one_tbl_len + pkthdr_index]));
                cmd = DRV_IOW(AutoGenPktPktHdr_t, AutoGenPktPktHdr_array_0_pktHdrUserdata_f + step *(one_tbl_len - 1 - pkthdr_index));
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, (up_ptr + index), cmd, &value));
            }

        }
    }
    else
    {
        for (index = 0; index < header_len / 8; index++)
        {
            SetAutoGenPktPktHdr(V, pktHdrUserdata0_f, &ds_pkt_hdr, DRV_SWAP32(p_hdr[index*2]));
            SetAutoGenPktPktHdr(V, pktHdrUserdata1_f, &ds_pkt_hdr, DRV_SWAP32(p_hdr[index*2 + 1]));
            cmd = DRV_IOW(AutoGenPktPktHdr_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, (up_ptr + index), cmd, &ds_pkt_hdr));
        }

        remnant = header_len % 8;
        index = header_len / 8;

        if(remnant%4)
        {
            p_tmp_hdr = (uint8*)p_pkt_header;
            max_array = remnant / 4;
            if (1 == remnant%4)
            {
                last_word = p_tmp_hdr[index * 8 + (remnant / 4) *4];
            }
            else if (2 == remnant%4)
            {
                last_word = (p_tmp_hdr[index * 8 + (remnant / 4) *4 ]) + (p_tmp_hdr[index * 8 + (remnant / 4) *4 + 1] << 8);
            }
            else if (3 == remnant%4)
            {
                last_word = (p_tmp_hdr[index * 8 + (remnant / 4) *4]) + (p_tmp_hdr[index * 8 + (remnant / 4) *4 + 1] << 8) + 
                          (p_tmp_hdr[index * 8 + (remnant / 4) * 4 + 2] << 16);
            }
        }
        else
        {
            max_array = remnant /4 ;
        }
        if (remnant)
        {
            sal_memset(&ds_pkt_hdr, 0, sizeof(AutoGenPktPktHdr_m));
            if (max_array)
            {
                SetAutoGenPktPktHdr(V, pktHdrUserdata0_f, &ds_pkt_hdr, DRV_SWAP32(p_hdr[index*2]));
                value = remnant%4? DRV_SWAP32(last_word): DRV_SWAP32(p_hdr[index*2 + 1]);
                SetAutoGenPktPktHdr(V, pktHdrUserdata1_f, &ds_pkt_hdr, value);
            }
            else
            {
                value = remnant%4? DRV_SWAP32(last_word): DRV_SWAP32(p_hdr[index*2]);
                SetAutoGenPktPktHdr(V, pktHdrUserdata0_f, &ds_pkt_hdr, value);
            }
            cmd = DRV_IOW(AutoGenPktPktHdr_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, (up_ptr + index), cmd, &ds_pkt_hdr));
        }
    }
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_npm_cal_rate(uint8 lchip, ctc_npm_cfg_t* p_cfg, uint32 autogen_clk)
{
    uint64 temp = 0;
    uint32 token_freq = 0;
    uint32 token_remainder = 0;
    AutoGenPktCtl_m pkt_ctl;
    uint32 cmd = 0;

    SYS_NPM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    /* cal token update frequency */
    temp = ((uint64)p_cfg->rate*SYS_NPM_1M_BYTES)/1000;
    token_freq = temp/(autogen_clk*1000);
    token_remainder = ((temp-token_freq*(autogen_clk*1000))*65536)/(autogen_clk*1000);

    SYS_NPM_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "token:%u, token_remainder:0x%x \n", (uint32)token_freq, (uint32)token_remainder);

    /*write hw*/
    cmd = DRV_IOR(AutoGenPktCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_cfg->session_id, cmd, &pkt_ctl));
    SetAutoGenPktCtl(V,tokenBytes_f, &pkt_ctl, token_freq);
    SetAutoGenPktCtl(V,tokenBytesFrac_f, &pkt_ctl, token_remainder);
    cmd = DRV_IOW(AutoGenPktCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_cfg->session_id, cmd, &pkt_ctl));
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_npm_set_auto_gen(uint8 lchip, ctc_npm_cfg_t* p_cfg)
{
    AutoGenPktPktCfg_m autogen_pkt_cfg;
    AutoGenPktEn_m autogen_en;
    AutoGenPktGlbCtl_m glb_ctl;
    uint32 cmd = 0;
    uint8 tx_mode = 0;
    uint8 is_use_period = 0;
    uint32 autogen_clock = 0;
    uint8 index = 0;
    uint8 sub_index = 0;
    uint32 field_id = 0;
    ctc_npm_pkt_format_t* p_pkt_format = NULL;
    uint32 burst_interval = 0;
    uint32 burst_idle = 0;
    uint32 tx_period = 0;
    uint32 tmp_value = 0;
    uint32 value = 0;
    uint64 burst_bytes = 0;
    sys_npm_session_t * npm_session = NULL;

    SYS_NPM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    npm_session = _sys_usw_npm_lkup_session(lchip, p_cfg->session_id);
    if (NULL == npm_session)
    {
        return CTC_E_NOT_EXIST;
    }

    p_pkt_format = &p_cfg->pkt_format;
     /*-autogen_clock = 32*1000/(autogen_clock>>8);*/
    autogen_clock = 1000;

    /* cal rate */
    CTC_ERROR_RETURN(_sys_usw_npm_cal_rate(lchip, p_cfg, autogen_clock));
    if (CTC_FLAG_ISSET(p_cfg->flag, CTC_NPM_CFG_FLAG_BURST_EN))
    {
        /*burst mode only support fix frame size*/
        if (p_cfg->pkt_format.frame_size_mode != 0)
        {
            SYS_NPM_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Feature not supported \n");
            return CTC_E_NOT_SUPPORT;

        }

        burst_bytes = ((uint64)p_cfg->burst_cnt)*(p_cfg->pkt_format.frame_size + p_cfg->pkt_format.ipg);
        burst_interval = (burst_bytes * autogen_clock * 8)/(p_cfg->rate);
        if (burst_bytes % (p_cfg->rate * 1000))
        {
            burst_interval += 1;
        }
    }
    else
    {
        burst_interval = autogen_clock*1000;
    }

    if (p_cfg->ibg == 0)
    {
        burst_idle = 0;
    }
    else
    {
        burst_idle = (p_cfg->ibg*autogen_clock)/1000;
    }

    cmd = DRV_IOR(AutoGenPktEn_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_cfg->session_id, cmd, &autogen_en));

    cmd = DRV_IOR(AutoGenPktPktCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_cfg->session_id, cmd, &autogen_pkt_cfg));

    switch(p_cfg->tx_mode)
    {
        case CTC_NPM_TX_MODE_CONTINUOUS:
            tx_mode = 1;
            is_use_period = 0;
            break;
        case CTC_NPM_TX_MODE_PACKET_NUM:
            tx_mode = 0;
            is_use_period = 0;
            break;
        case CTC_NPM_TX_MODE_PERIOD:
            tx_mode = 1;
            is_use_period = 1;

            /*cal period */
            if ((burst_interval+burst_idle) == 0)
            {
                return CTC_E_INVALID_PARAM;
            }
            tx_period = ((uint64)p_cfg->tx_period*autogen_clock*1000)/(burst_idle+burst_interval);

            break;
        default:
            break;
    }

    /*cfg tx mode*/
    SetAutoGenPktPktCfg(V, txMode_f, &autogen_pkt_cfg,  tx_mode);
    SetAutoGenPktPktCfg(V, isUsePeriod_f, &autogen_pkt_cfg,  is_use_period);
    SetAutoGenPktPktCfg(V, burstTxInterval_f, &autogen_pkt_cfg, burst_interval);
    SetAutoGenPktPktCfg(V, burstIdleInterval_f, &autogen_pkt_cfg, burst_idle);
    SetAutoGenPktEn(V, periodCnt_f, &autogen_en,  tx_period);
    SetAutoGenPktEn(V, txPktCnt_f, &autogen_en,  p_cfg->packet_num);
    SetAutoGenPktEn(V, burstTxCnt_f, &autogen_en, burst_interval);
    SetAutoGenPktEn(V, burstIdleCnt_f, &autogen_en, burst_idle);

    /*cfg seq number insert*/
    SetAutoGenPktPktCfg(V, seqNumOffset_f, &autogen_pkt_cfg, p_pkt_format->seq_num_offset + SYS_USW_PKT_HEADER_LEN);
    SetAutoGenPktPktCfg(V, txSeqNumEn_f , &autogen_pkt_cfg, (CTC_FLAG_ISSET(p_cfg->flag, CTC_NPM_CFG_FLAG_SEQ_EN)?1:0));
    SetAutoGenPktPktCfg(V, udpChksumEn_f , &autogen_pkt_cfg, p_pkt_format->chksum_offset ? 1:0);
    SetAutoGenPktPktCfg(V, udpChksumOffset_f , &autogen_pkt_cfg, p_pkt_format->chksum_offset + SYS_USW_PKT_HEADER_LEN);
    if (CTC_FLAG_ISSET(p_cfg->flag, CTC_NPM_CFG_FLAG_SEQ_EN))
    {
        value = p_cfg->pkt_format.seq_num_offset;
        cmd = DRV_IOW(AutoGenRxProc_t, AutoGenRxProc_seqNoOffset_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, p_cfg->session_id, cmd, &value));
    }
    if (CTC_FLAG_ISSET(p_cfg->flag, CTC_NPM_CFG_FLAG_TS_EN))
    {
        uint32 mux_type = 0;
        if (!CTC_FLAG_ISSET(p_cfg->flag, CTC_NPM_CFG_FLAG_MCAST) && !CTC_IS_LINKAGG_PORT(p_cfg->dest_gport))
        {
            CTC_ERROR_RETURN(sys_usw_port_api_get_internal_property(lchip, p_cfg->dest_gport, SYS_PORT_PROP_MUX_PORT_TYPE, &mux_type));
        }
        value =  p_cfg->pkt_format.ts_offset + (mux_type == 2? 4 : 0);
        cmd = DRV_IOW(AutoGenRxProc_t, AutoGenRxProc_tsOffset_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, p_cfg->session_id, cmd, &value));
    }
    if (CTC_FLAG_ISSET(p_cfg->flag, CTC_NPM_CFG_FLAG_VRF_EN))
    {
        value =  1;
        cmd = DRV_IOW(AutoGenRxProc_t, AutoGenRxProc_twampWithVrf_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, p_cfg->session_id, cmd, &value));
    }
    if (CTC_FLAG_ISSET(p_cfg->flag, CTC_NPM_CFG_FLAG_NTP_TS))
    {
        npm_session->session_stats.is_ntp_ts = 1;
    }
    else
    {
        npm_session->session_stats.is_ntp_ts = 0;
    }

    /*cfg packet size*/
    if (p_pkt_format->frame_size_mode == 0)
    {
        /*fix size*/
        SetAutoGenPktPktCfg(V, txPktSize_f, &autogen_pkt_cfg,  p_pkt_format->frame_size);
        SetAutoGenPktPktCfg(V, txPktSizeType_f, &autogen_pkt_cfg,  0);
    }
    else if (p_pkt_format->frame_size_mode == 1)
    {
        /*increase*/
        SetAutoGenPktPktCfg(V, txPktSize_f, &autogen_pkt_cfg,  p_pkt_format->frame_size);
        SetAutoGenPktPktCfg(V, txPktMinSize_f, &autogen_pkt_cfg,  p_pkt_format->min_frame_size);
        SetAutoGenPktPktCfg(V, txPktSizeType_f, &autogen_pkt_cfg,  2);
    }
    else if (p_pkt_format->frame_size_mode == 2)
    {
        /*emix*/
        SetAutoGenPktPktCfg(V, txPktSizeType_f, &autogen_pkt_cfg,  3);
        SetAutoGenPktPktCfg(V, eMixArraySize_f, &autogen_pkt_cfg,  (p_pkt_format->emix_size_num - 1));
        for (index = 0; index < p_pkt_format->emix_size_num; index++)
        {
            cmd = DRV_IOR(AutoGenPktGlbCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &glb_ctl));

            for (sub_index = 0; sub_index < CTC_NPM_MAX_EMIX_NUM; sub_index++)
            {
                field_id = AutoGenPktGlbCtl_g_0_size_f + sub_index;
                drv_get_field(lchip, AutoGenPktGlbCtl_t, field_id, &glb_ctl, &tmp_value);
                if (p_pkt_format->emix_size[index] == tmp_value)
                {
                    value = sub_index;
                    break;
                }
            }

            field_id = AutoGenPktPktCfg_eMixArray_0_sizeIdx_f + index;
            drv_set_field(lchip, AutoGenPktPktCfg_t, field_id, &autogen_pkt_cfg, &value);

        }
    }

    /*cfg pattern*/
    SetAutoGenPktPktCfg(V, patternType_f, &autogen_pkt_cfg,  p_pkt_format->pattern_type);
    SetAutoGenPktPktCfg(V, repeatPattern_f, &autogen_pkt_cfg,  p_pkt_format->repeat_pattern);
    SetAutoGenPktPktCfg(V, ipg_f, &autogen_pkt_cfg,  p_pkt_format->ipg);

    /*cfg timeout*/
    if (p_cfg->timeout)
    {
        SetAutoGenPktPktCfg(V, isUseTimeout_f, &autogen_pkt_cfg,  1);
        if ((burst_interval+burst_idle) == 0)
        {
            return CTC_E_INVALID_PARAM;
        }
        tx_period = ((uint64)p_cfg->timeout*autogen_clock*1000)/(burst_idle+burst_interval);
        SetAutoGenPktPktCfg(V, timeOutCfg_f, &autogen_pkt_cfg,  tx_period);
    }
    else
    {
        SetAutoGenPktPktCfg(V, isUseTimeout_f, &autogen_pkt_cfg,  0);
    }

    /*cfg burst*/
    if (CTC_FLAG_ISSET(p_cfg->flag, CTC_NPM_CFG_FLAG_BURST_EN))
    {
        if (p_cfg->ibg)
        {
            if (p_cfg->ibg*autogen_clock > 0xFFFFFFFF)
            {
                return CTC_E_INVALID_PARAM;
            }
            value = (p_cfg->ibg*autogen_clock)/1000;
            SetAutoGenPktPktCfg(V, burstIdleInterval_f, &autogen_pkt_cfg, value);
        }
    }

    SetAutoGenPktPktCfg(V, isHaveEndTlv_f, &autogen_pkt_cfg,  1);
    SetAutoGenPktPktCfg(V, pktHdrLen_f, &autogen_pkt_cfg,  p_pkt_format->header_len + SYS_USW_PKT_HEADER_LEN);

    /*cfg AutoGenPktPktCfg */
    cmd = DRV_IOW(AutoGenPktPktCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_cfg->session_id, cmd, &autogen_pkt_cfg));

    /*cfg AutoGenPktEn */
    cmd = DRV_IOW(AutoGenPktEn_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_cfg->session_id, cmd, &autogen_en));

    return CTC_E_NONE;

}


STATIC int32
_sys_usw_npm_show_session_status(uint8 lchip, ctc_npm_cfg_t* p_cfg)
{
    AutoGenPktPktCfg_m autogen_pkt_cfg;
    AutoGenPktEn_m autogen_en;
    AutoGenPktGlbCtl_m glb_ctl;
    uint32 cmd = 0;
    uint8 tx_mode = 0;
    uint8 is_use_period = 0;
    uint32 autogen_clock = 1000;
    uint32 burst_interval = 0;
    uint32 burst_idle = 0;
    uint32 tx_period = 0;
    uint32 value = 0;
    uint8  index = 0;
    uint32 tmp_value = 0;
    uint32 field_id = 0;

    SYS_NPM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    sal_memset(&autogen_pkt_cfg, 0, sizeof(AutoGenPktPktCfg_m));
    sal_memset(&autogen_en, 0, sizeof(AutoGenPktEn_m));


    cmd = DRV_IOR(AutoGenPktEn_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_cfg->session_id, cmd, &autogen_en));
    if (!GetAutoGenPktEn(V, autoGenEn_f, &autogen_en))
    {
        return CTC_E_NONE;
    }

    cmd = DRV_IOR(AutoGenPktPktCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_cfg->session_id, cmd, &autogen_pkt_cfg));

    tx_mode = GetAutoGenPktPktCfg(V, txMode_f, &autogen_pkt_cfg);
    is_use_period = GetAutoGenPktPktCfg(V, isUsePeriod_f, &autogen_pkt_cfg);
    if (1 == tx_mode && 0 == is_use_period)
    {
        p_cfg->tx_mode = CTC_NPM_TX_MODE_CONTINUOUS;
    }
    else if(0 == tx_mode && 0 == is_use_period)
    {
        p_cfg->tx_mode = CTC_NPM_TX_MODE_PACKET_NUM;
        p_cfg->packet_num = GetAutoGenPktEn(V, txPktCnt_f, &autogen_en);
    }
    else if(1 == tx_mode && 1 == is_use_period)
    {
        p_cfg->tx_mode = CTC_NPM_TX_MODE_PERIOD;

        burst_interval = GetAutoGenPktPktCfg(V, burstTxInterval_f, &autogen_pkt_cfg);
        burst_idle = GetAutoGenPktPktCfg(V, burstIdleInterval_f, &autogen_pkt_cfg);
        if ((burst_interval + burst_idle) == 0)
        {
            return CTC_E_INVALID_PARAM;
        }
        tx_period = GetAutoGenPktEn(V, periodCnt_f, &autogen_en);
        p_cfg->tx_period = ((uint64)tx_period *(burst_idle + burst_interval)) / autogen_clock / 1000 ;
    }

    p_cfg->pkt_format.seq_num_offset = GetAutoGenPktPktCfg(V, seqNumOffset_f, &autogen_pkt_cfg) - SYS_USW_PKT_HEADER_LEN;

    /*fix size*/
    if (0 == GetAutoGenPktPktCfg(V, txPktSizeType_f, &autogen_pkt_cfg))
    {
        p_cfg->pkt_format.frame_size_mode = 0;
        p_cfg->pkt_format.frame_size = GetAutoGenPktPktCfg(V, txPktSize_f, &autogen_pkt_cfg);
    }

    else if (2 == GetAutoGenPktPktCfg(V, txPktSizeType_f, &autogen_pkt_cfg))
    {
        /*increase*/
        p_cfg->pkt_format.frame_size_mode = 1;
        p_cfg->pkt_format.frame_size = GetAutoGenPktPktCfg(V, txPktSize_f, &autogen_pkt_cfg);
        p_cfg->pkt_format.min_frame_size = GetAutoGenPktPktCfg(V, txPktMinSize_f, &autogen_pkt_cfg);

    }
    else if (3 == GetAutoGenPktPktCfg(V, txPktSizeType_f, &autogen_pkt_cfg))
    {
        /*emix*/
        p_cfg->pkt_format.emix_size_num = GetAutoGenPktPktCfg(V, eMixArraySize_f, &autogen_pkt_cfg) + 1;
        p_cfg->pkt_format.frame_size_mode = 2;

        cmd = DRV_IOR(AutoGenPktGlbCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &glb_ctl));
        for (index = 0; index < CTC_NPM_MAX_EMIX_NUM; index++)
        {
            field_id = AutoGenPktGlbCtl_g_0_size_f + index;
            drv_get_field(lchip, AutoGenPktGlbCtl_t, field_id, &glb_ctl, &tmp_value);
            p_cfg->pkt_format.emix_size[index] = tmp_value;
        }

    }

    /*cfg pattern*/
    p_cfg->pkt_format.pattern_type = GetAutoGenPktPktCfg(V, patternType_f, &autogen_pkt_cfg);
    p_cfg->pkt_format.repeat_pattern = GetAutoGenPktPktCfg(V, repeatPattern_f, &autogen_pkt_cfg);
    p_cfg->pkt_format.ipg= GetAutoGenPktPktCfg(V, ipg_f, &autogen_pkt_cfg);

    /*cfg timeout*/
    p_cfg->timeout = GetAutoGenPktPktCfg(V, isUseTimeout_f, &autogen_pkt_cfg)? 1 : 0;

    if (GetAutoGenPktPktCfg(V, burstIdleInterval_f, &autogen_pkt_cfg))
    {
        CTC_SET_FLAG(p_cfg->flag, CTC_NPM_CFG_FLAG_BURST_EN);
    }

    value = GetAutoGenPktPktCfg(V, burstIdleInterval_f, &autogen_pkt_cfg );
    p_cfg->ibg = value *1000 /autogen_clock;

    return CTC_E_NONE;

}

STATIC int32
_sys_usw_npm_show_lite_session_status(uint8 lchip, ctc_npm_cfg_t* p_cfg)
{
    uint32 cmd = 0;
    DsOamTwampCfg_m twampcfg;
    DsOamTwampTxCfg_m twamp_tx_cfg;
    sys_npm_lite_session_t* npm_lite_session = NULL;

    SYS_NPM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    npm_lite_session = (sys_npm_lite_session_t*)ctc_vector_get(g_npm_master[lchip]->session_lite, p_cfg->session_id);
    if(!npm_lite_session)
    {
        return CTC_E_NOT_EXIST;
    }

    sal_memset(&twampcfg,0,sizeof(DsOamTwampCfg_m));
    sal_memset(&twamp_tx_cfg,0,sizeof(DsOamTwampTxCfg_m));

    cmd = DRV_IOR(DsOamTwampCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, npm_lite_session->twamp_idx, cmd, &twampcfg));
    p_cfg->dm_stats_mode= GetDsOamTwampCfg(V, measureType_f, &twampcfg);

    cmd = DRV_IOR(DsOamTwampTxCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, npm_lite_session->twamp_idx, cmd, &twamp_tx_cfg));

    p_cfg->rate = GetDsOamTwampTxCfg(V, periodIntervalCfg_f, &twamp_tx_cfg);
    p_cfg->lite_cfg.dm_tx_type= GetDsOamTwampTxCfg(V, txDmType_f, &twamp_tx_cfg);
    return CTC_E_NONE;

}


STATIC int32
_sys_usw_npm_clear_lite_stats(uint8 lchip, uint32 session_id)
{
    uint32 cmd =0;
    sys_npm_lite_session_t* npm_lite_session = NULL;
    DsOamTwampStats_m ds_twamp_stats;
    sal_memset(&ds_twamp_stats, 0, sizeof(ds_twamp_stats));
    npm_lite_session = (sys_npm_lite_session_t*)ctc_vector_get(g_npm_master[lchip]->session_lite, SYS_NPM_LITE_SESSION_CONVERT(session_id));
    if (npm_lite_session == NULL)
    {
        SYS_NPM_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Not found npm session\n");
        return CTC_E_NOT_EXIST;
    }
    cmd = DRV_IOW(DsOamTwampStats_t, DRV_ENTRY_FLAG);
	SetDsOamTwampStats(V, statsInit_f, &ds_twamp_stats, 1);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, npm_lite_session->twamp_idx, cmd, &ds_twamp_stats));
    sal_memset(&npm_lite_session->lite_stats, 0, sizeof(sys_npm_lite_stats_t));
    sal_memset(&npm_lite_session->session_stats, 0, sizeof(sys_npm_common_stats_t));
    sal_memset(&npm_lite_session->lite_old_stats, 0, sizeof(sys_npm_lite_stats_t));
    sal_memset(&npm_lite_session->session_old_stats, 0, sizeof(sys_npm_common_stats_t));
    npm_lite_session->session_stats.min_delay = SYS_NPM_UINT64_MAX;
    npm_lite_session->lite_stats.two_way_min_jitter= CTC_MAX_UINT32_VALUE;
    npm_lite_session->lite_stats.far_min_jitter = CTC_MAX_UINT32_VALUE;
    npm_lite_session->lite_stats.near_min_jitter = CTC_MAX_UINT32_VALUE;
    return CTC_E_NONE;
}
STATIC int32
_sys_usw_npm_clear_stats(uint8 lchip, uint32 session_id)
{
    uint32 cmd = 0;
    uint32 value = 0;
    sys_npm_session_t * npm_session = NULL;
    AutoGenPktTxPktStats_m tx_stats;
    AutoGenPktRxPktStats_m rx_stats;
    AutoGenPktTxPktAck_m tx_ack;
    SYS_NPM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    sal_memset(&tx_stats, 0, sizeof(tx_stats));
    sal_memset(&rx_stats, 0, sizeof(rx_stats));
    sal_memset(&tx_ack, 0, sizeof(tx_ack));
    if (CTC_NPM_IS_LITE_SESSION(session_id))
    {
       CTC_ERROR_RETURN(_sys_usw_npm_clear_lite_stats(lchip,session_id));
       return CTC_E_NONE;
    }
    npm_session = _sys_usw_npm_lkup_session(lchip, session_id);
    if (NULL == npm_session)
    {
        return CTC_E_NOT_EXIST;
    }

    /* clear AutoGen tx stats */
    cmd = DRV_IOW(AutoGenPktTxPktStats_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, session_id, cmd, &tx_stats));

    /* clear AutoGen rx stats */
    SetAutoGenPktRxPktStats(V, statsInit_f, &rx_stats, 1);
    cmd = DRV_IOW(AutoGenPktRxPktStats_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, session_id, cmd, &rx_stats));

    /* clear AutoGen txAck stats */
    cmd = DRV_IOR(AutoGenPktTxPktAck_t, AutoGenPktTxPktAck_measureType_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, session_id, cmd, &value));
    cmd = DRV_IOW(AutoGenPktTxPktAck_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, session_id, cmd, &tx_ack));
    cmd = DRV_IOW(AutoGenPktTxPktAck_t, AutoGenPktTxPktAck_measureType_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, session_id, cmd, &value));
    /* clear stats in DB*/
    npm_session->rx_bytes_all = 0;
    npm_session->tx_bytes_all = 0;
    npm_session->session_stats.rx_pkts_all = 0;
    npm_session->session_stats.tx_pkts_all = 0;
    npm_session->session_stats.last_ts = 0;
    npm_session->session_stats.total_delay_all = 0;
    npm_session->total_far_delay_all = 0;
    npm_session->session_stats.max_jitter = 0;
    npm_session->session_stats.total_jitter_all = 0;
    npm_session->session_stats.max_delay = 0;
    npm_session->session_stats.disorder_pkts= 0;
    npm_session->continuous_non_ses_cnt = 0;
    npm_session->continuous_ses_cnt = 0;
    npm_session->ses_cnt = 0;
    npm_session->non_ses_cnt = 0;
    npm_session->in_avl_period = 1;
    npm_session->seconds = 0;
    npm_session->max_rx_ir = 0;
    npm_session->min_rx_ir = SYS_NPM_UINT64_MAX;
    npm_session->avl_periods = 0;
    npm_session->unavl_periods = 0;
    npm_session->session_stats.min_delay = SYS_NPM_UINT64_MAX;
    npm_session->session_stats.min_jitter = CTC_MAX_UINT32_VALUE;

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_npm_get_rx_tx_stats(uint8 lchip, uint8 session_id, uint8 dir, uint32* stats)
{
    uint32 cmd = 0;
    uint64 tmp_1st = 0;
    uint64 tmp_2nd = 0;
    uint32 field_value = 0;
    uint32 tmp[2] = {0};
    fld_id_t field_id;
    uint32 table_id = 0;
    uint32 stats_tmp[16] = {0};

    /*only for D2 NPM stats clearOnRead*/
    SYS_NPM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    LCHIP_CHECK(lchip);

    table_id = dir ? AutoGenPktTxPktStats_t : AutoGenPktRxPktStats_t;
    field_id = dir ? AutoGenPktTxPktStats_txBytes_f : AutoGenPktRxPktStats_totalDTs_f;

    do
    {
        /*first read stats*/
        cmd = DRV_IOR(table_id, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, session_id, cmd, stats));
        sal_memset(tmp, 0, sizeof(tmp));
        DRV_GET_FIELD(lchip, table_id, field_id, stats, tmp);
        tmp_1st = ((uint64)tmp[1] << 32) + tmp[0];

        field_value = 0;
        cmd = DRV_IOW(AutoGenPktGlbCtl_t, AutoGenPktGlbCtl_clearOnRead_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));

        /*second read stats*/
        cmd = DRV_IOR(table_id, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, session_id, cmd, &stats_tmp));

        field_value = 1;
        cmd = DRV_IOW(AutoGenPktGlbCtl_t, AutoGenPktGlbCtl_clearOnRead_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));

        sal_memset(tmp, 0, sizeof(tmp));
        DRV_GET_FIELD(lchip, table_id, field_id, &stats_tmp, tmp);
        tmp_2nd = ((uint64)tmp[1] << 32) + tmp[0];
    }
    while (tmp_2nd > tmp_1st);

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_npm_free_node_data(void* node_data, void* user_data)
{
    mem_free(node_data);
    return CTC_E_NONE;
}

#define __SYS_INTERFACE__

int32
sys_usw_npm_set_config(uint8 lchip, ctc_npm_cfg_t* p_cfg)
{
    MsPacketHeader_m bridge_header;
    void* p_pkt_header = NULL;
    ctc_npm_pkt_format_t* p_pkt_format = NULL;
    int32 ret = CTC_E_NONE;
    uint32 cmd = 0;
    uint32 autogen_en = 0;
    uint32 value = 0;
    sys_npm_session_t * npm_session=NULL;
    uint8 is_alloc = 0;
    uint8 index = 0;



    SYS_NPM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    CTC_PTR_VALID_CHECK(p_cfg);
    SYS_NPM_INIT_CHECK(lchip);

    if (p_cfg->pkt_format.frame_size_mode < 2)
    {
        /*checksum+crc:6*/
        CTC_MAX_VALUE_CHECK(p_cfg->pkt_format.chksum_offset, p_cfg->pkt_format.frame_size - 6);
    }
    else if (p_cfg->pkt_format.frame_size_mode == 2)
    {
        for (index = 0; index < p_cfg->pkt_format.emix_size_num; index++)
        {
            value = p_cfg->pkt_format.emix_size[index];
            CTC_MAX_VALUE_CHECK(p_cfg->pkt_format.chksum_offset, value - 6);
        }
    }
    NPM_LOCK(lchip);
    if (CTC_FLAG_ISSET(p_cfg->flag, CTC_NPM_CFG_FLAG_TWAMP_LITE)
        ||CTC_FLAG_ISSET(p_cfg->flag, CTC_NPM_CFG_FLAG_DMM_LITE))
    {
        if (MCHIP_NPM(lchip)->set_lite_cfg)
        {
            SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_NPM, SYS_WB_APPID_NPM_SUBID_SESSION_LITE, 1);
            CTC_ERROR_RETURN_WITH_UNLOCK(MCHIP_NPM(lchip)->set_lite_cfg(lchip, p_cfg), g_npm_master[lchip]->npm_mutex);
        }
        NPM_UNLOCK(lchip);
        return CTC_E_NONE;
    }
   if (p_cfg->session_id >= MCHIP_CAP(SYS_CAP_NPM_SESSION_NUM))
   {
        NPM_UNLOCK(lchip);
        return CTC_E_INVALID_PARAM;
   }

   npm_session = _sys_usw_npm_lkup_session(lchip, p_cfg->session_id);
   if (NULL == npm_session)
   {
       npm_session = (sys_npm_session_t*)mem_malloc(MEM_NPM_MODULE, sizeof(sys_npm_session_t));
       if (npm_session)
       {
           sal_memset(npm_session, 0, sizeof(sys_npm_session_t));
           npm_session->session_id = p_cfg->session_id;
           npm_session->session_stats.min_delay = SYS_NPM_UINT64_MAX;
           npm_session->session_stats.min_jitter = CTC_MAX_UINT32_VALUE;
           npm_session->in_avl_period = 1;
           npm_session->flr_for_ses = 50;
           npm_session->min_rx_ir = SYS_NPM_UINT64_MAX;
           npm_session->avl_period_thrd = 10;
       }
       else
       {
           NPM_UNLOCK(lchip);
           return CTC_E_NO_MEMORY;
       }
       if (FALSE == ctc_vector_add(g_npm_master[lchip]->session, p_cfg->session_id, npm_session))
       {
           mem_free(npm_session);
           NPM_UNLOCK(lchip);
           return  CTC_E_NO_MEMORY;
       }
       is_alloc = 1;
       if (DRV_FROM_TMM(lchip))
       {
           if (1 == g_npm_master[lchip]->session->used_cnt && !g_npm_master[lchip]->session_lite->used_cnt)
           {
                CTC_ERROR_GOTO(sys_usw_dma_set_npm_stats_enable(lchip, TRUE), ret, error_proc0);
           }
       }
   }


    sal_memset(&bridge_header, 0, sizeof(MsPacketHeader_m));

    if (1 == p_cfg->dm_stats_mode)
    {
        value = 0;
    }
    else if (2 == p_cfg->dm_stats_mode)
    {
        value = 1;
    }
    else
    {
        value = 2;
    }
    cmd = DRV_IOW(AutoGenPktTxPktAck_t, AutoGenPktTxPktAck_measureType_f);
    CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, p_cfg->session_id, cmd, &value), ret, error_proc1);

    /*Config for Rx roler, only care ts_offset and seq_num_offset*/
    if (CTC_FLAG_ISSET(p_cfg->flag, CTC_NPM_CFG_FLAG_RX_ROLE_EN))
    {
        value = p_cfg->rx_role_en;
        cmd = DRV_IOW(AutoGenRxProc_t, AutoGenRxProc_autoGenEn_f);
        CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, p_cfg->session_id, cmd, &value), ret, error_proc1);
        if (CTC_FLAG_ISSET(p_cfg->flag, CTC_NPM_CFG_FLAG_SEQ_EN))
        {
            value = p_cfg->pkt_format.seq_num_offset;
            cmd = DRV_IOW(AutoGenRxProc_t, AutoGenRxProc_seqNoOffset_f);
            CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, p_cfg->session_id, cmd, &value), ret, error_proc1);
        }
        if (CTC_FLAG_ISSET(p_cfg->flag, CTC_NPM_CFG_FLAG_TS_EN))
        {
			value =  p_cfg->pkt_format.ts_offset;
            cmd = DRV_IOW(AutoGenRxProc_t, AutoGenRxProc_tsOffset_f);
            CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, p_cfg->session_id, cmd, &value), ret, error_proc1);
        }
        NPM_UNLOCK(lchip);
        return CTC_E_NONE;
    }

        if (CTC_FLAG_ISSET(p_cfg->flag, CTC_NPM_CFG_FLAG_FLR_FOR_SES))
        {
            npm_session->flr_for_ses= p_cfg->flr_for_ses;
        }
        if (CTC_FLAG_ISSET(p_cfg->flag, CTC_NPM_CFG_FLAG_AVL_PERIOD_THRD))
        {
            npm_session->avl_period_thrd = p_cfg->avl_period_thrd;
        }

    /*Light Mode*/
    value = p_cfg->lite_cfg.mode == 2? 1 : 0;
    cmd = DRV_IOW(AutoGenPktCtl_t, AutoGenPktCtl_twampLightEn_f);
    CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, p_cfg->session_id, cmd, &value), ret, error_proc1);

    /*1. parameter check */
    CTC_ERROR_GOTO(_sys_usw_npm_parameter_check(lchip, p_cfg), ret, error_proc1);

    cmd = DRV_IOR(AutoGenPktEn_t, AutoGenPktEn_autoGenEn_f);
    CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, p_cfg->session_id, cmd, &autogen_en), ret, error_proc1);
    if (autogen_en)
    {
        ret = CTC_E_HW_BUSY;
        goto error_proc1;
    }
    p_pkt_format = &p_cfg->pkt_format;
    p_pkt_header = (uint8*)mem_malloc(MEM_NPM_MODULE, (p_pkt_format->header_len + SYS_USW_PKT_HEADER_LEN));
    if (NULL == p_pkt_header)
    {
        ret = CTC_E_NO_MEMORY;
        goto error_proc1;
    }

    /*2. cfg bridge header */
    CTC_ERROR_GOTO(_sys_usw_npm_set_bridge_hdr(lchip, p_cfg, &bridge_header), ret, error_proc2);

    sal_memcpy((uint8*)p_pkt_header, (uint8*)&bridge_header, SYS_USW_PKT_HEADER_LEN - (DRV_FROM_TMM(lchip)? SYS_USW_PKT_HDR_TAIL_LEN : 0) - (DRV_FROM_AT(lchip)? SYS_USW_PKT_HDR_XBUS_LEN : 0));
    sal_memcpy((uint8*)((uint8*)p_pkt_header + SYS_USW_PKT_HEADER_LEN), (uint8*)p_pkt_format->pkt_header, p_pkt_format->header_len);

    /*3. cfg user defined packet header */
    CTC_ERROR_GOTO(_sys_usw_npm_set_user_data(lchip, p_cfg, p_pkt_header), ret, error_proc2);

    /*4. cfg AutoGen rate */
    CTC_ERROR_GOTO(_sys_usw_npm_set_auto_gen(lchip, p_cfg), ret, error_proc2);

    /* TM and TM2 use OamRxProcEtherCtl.dmProcByCpu to decide to cpu or not */
    if (CTC_FLAG_ISSET(p_cfg->flag, CTC_NPM_CFG_FLAG_DMR_NOT_TO_CPU) && DRV_IS_DUET2(lchip))
    {
        CTC_BIT_SET(g_npm_master[lchip]->config_dmm_bitmap, p_cfg->session_id);
    }
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_NPM, SYS_WB_APPID_NPM_SUBID_MASTER, 1);
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_NPM, SYS_WB_APPID_NPM_SUBID_SESSION, 1);
    /*5. clear stats */
    CTC_ERROR_GOTO(_sys_usw_npm_clear_stats(lchip, p_cfg->session_id), ret, error_proc2);

    if (p_pkt_header)
    {
        mem_free(p_pkt_header);
    }
    NPM_UNLOCK(lchip);
    return CTC_E_NONE;

    error_proc2:
    if (p_pkt_header)
    {
        mem_free(p_pkt_header);
    }
    error_proc1:
    if (is_alloc)
    {
        if (DRV_FROM_TMM(lchip))
        {
            if (1 == g_npm_master[lchip]->session->used_cnt && !g_npm_master[lchip]->session_lite->used_cnt)
            {
                sys_usw_dma_set_npm_stats_enable(lchip, FALSE);
            }
        }
    }
    error_proc0:
    if (is_alloc)
    {
        ctc_vector_del(g_npm_master[lchip]->session, p_cfg->session_id);
        if (npm_session)
        {
            mem_free(npm_session);
        }
    }
    NPM_UNLOCK(lchip);
    return ret;
}





int32
sys_usw_npm_binding_mep(uint8 lchip, uint32 session_id, uint32 mep_idx, uint32* twamp_idx)
{
    sys_npm_lite_session_t* npm_lite_session = NULL;
    SYS_NPM_INIT_CHECK(lchip);
    
    npm_lite_session = (sys_npm_lite_session_t*)ctc_vector_get(g_npm_master[lchip]->session_lite, SYS_NPM_LITE_SESSION_CONVERT(session_id));
    if (npm_lite_session == NULL)
    {
        SYS_NPM_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Not found npm session\n");
        return CTC_E_NOT_EXIST;
    }
    npm_lite_session->mep_idx = mep_idx;
    *twamp_idx = npm_lite_session->twamp_idx;
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_NPM, SYS_WB_APPID_NPM_SUBID_SESSION_LITE, 1);
    return CTC_E_NONE;
}

int32
sys_usw_npm_unbinding_mep(uint8 lchip, uint32 session_id)
{
    sys_npm_lite_session_t* npm_lite_session = NULL;
    SYS_NPM_INIT_CHECK(lchip);
    
    npm_lite_session = (sys_npm_lite_session_t*)ctc_vector_get(g_npm_master[lchip]->session_lite, SYS_NPM_LITE_SESSION_CONVERT(session_id));
    if (npm_lite_session == NULL)
    {
        SYS_NPM_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Not found npm session\n");
        return CTC_E_NOT_EXIST;
    }
    npm_lite_session->mep_idx = 0;
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_NPM, SYS_WB_APPID_NPM_SUBID_SESSION_LITE, 1);
    return CTC_E_NONE;
}
int32
sys_usw_npm_set_transmit_en(uint8 lchip, uint32 session_id, uint8 enable)
{
    uint32 cmd = 0;
    int32 ret = CTC_E_NONE;
    uint32 value = 0;
    uint32 dest_map = 0;
    uint8  modify_dmm_destmap = 0;
    uint8  gchip = 0;
    DsOamTwampTxCfg_m ds_twamp_tx_cfg;
    sys_npm_session_t * npm_session = NULL;
    sys_cpu_reason_dest_info_t dest_info;
    sal_memset(&dest_info, 0, sizeof(dest_info));

    SYS_NPM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_NPM_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "lchip:%d, session_id:%u, enable:%d \n", lchip, SYS_NPM_LITE_SESSION_CONVERT(session_id), enable);
    SYS_NPM_INIT_CHECK(lchip);

    NPM_LOCK(lchip);
    if (CTC_NPM_IS_LITE_SESSION(session_id))
    {
        sys_npm_lite_session_t* npm_lite_session = NULL;

        sal_memset(&ds_twamp_tx_cfg, 0, sizeof(ds_twamp_tx_cfg));
        npm_lite_session = (sys_npm_lite_session_t*)ctc_vector_get(g_npm_master[lchip]->session_lite, SYS_NPM_LITE_SESSION_CONVERT(session_id));
        if (NULL == npm_lite_session)
        {
            NPM_UNLOCK(lchip);
            return CTC_E_NOT_EXIST;
        }
        if (npm_lite_session->mode != 0)
        {
            SYS_NPM_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Can't config tranmit enable for reflecter\n");
            NPM_UNLOCK(lchip);
            return CTC_E_INVALID_CONFIG;
        }
        cmd  = DRV_IOR(DsOamTwampTxCfg_t, DRV_ENTRY_FLAG);
        CTC_ERROR_GOTO(DRV_IOCTL(lchip, npm_lite_session->twamp_idx, cmd, &ds_twamp_tx_cfg), ret, error1);

        SetDsOamTwampTxCfg(V, periodTestEn_f                  , &ds_twamp_tx_cfg , enable? 1 : 0);
        if (!enable)
        {
            SetDsOamTwampTxCfg(V, txSeqNum_f                  , &ds_twamp_tx_cfg , 0);
        }
        else
        {
            npm_lite_session->synced = 0;
        }
        cmd  = DRV_IOW(DsOamTwampTxCfg_t, DRV_ENTRY_FLAG);
        CTC_ERROR_GOTO(DRV_IOCTL(lchip, npm_lite_session->twamp_idx, cmd, &ds_twamp_tx_cfg), ret, error1);
        NPM_UNLOCK(lchip);
        return ret;
    }

    npm_session = _sys_usw_npm_lkup_session(lchip, session_id);
    if (NULL == npm_session)
    {
        NPM_UNLOCK(lchip);
        return CTC_E_NOT_EXIST;
    }

    CTC_ERROR_GOTO(sys_usw_cpu_reason_get_info(lchip, CTC_PKT_CPU_REASON_OAM + CTC_OAM_EXCP_DM_TO_CPU, &dest_info), ret, error1);
    if (enable)
    {
        if (CTC_IS_BIT_SET(g_npm_master[lchip]->config_dmm_bitmap, session_id) && DRV_IS_DUET2(lchip))
        {
            if (!g_npm_master[lchip]->tx_dmm_en_bitmap)
            {
                modify_dmm_destmap  = 1;
            }
            CTC_BIT_SET(g_npm_master[lchip]->tx_dmm_en_bitmap, session_id);
            SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_NPM, SYS_WB_APPID_NPM_SUBID_MASTER, 1);
        }
        if ((modify_dmm_destmap) && DRV_IS_DUET2(lchip))
        {
            sys_usw_get_gchip_id(lchip, &gchip);
            dest_map = SYS_ENCODE_DESTMAP(gchip, SYS_RSV_PORT_DROP_ID);
            cmd = DRV_IOW(DsOamExcp_t, DsOamExcp_destMap_f);
            CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, SYS_OAM_EXCP_ETH_DM, cmd, &dest_map), ret, error1);
        }

        value = 1;
        cmd = DRV_IOW(AutoGenRxProc_t, AutoGenRxProc_autoGenEn_f);
        CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, session_id, cmd, &value), ret, error2);
        cmd = DRV_IOW(AutoGenPktEn_t, AutoGenPktEn_autoGenEn_f);
        CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, session_id, cmd, &value), ret, error2);
        if (DRV_FROM_TMM(lchip))
        {
            cmd = DRV_IOR(AutoGenSessionEnCtl_t, AutoGenSessionEnCtl_enBitmap_f);
            CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, &value), ret, error2);
            CTC_BIT_SET(value, session_id);
            cmd = DRV_IOW(AutoGenSessionEnCtl_t, AutoGenSessionEnCtl_enBitmap_f);
            CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, &value), ret, error2);
        }
    }
    else
    {
        if (DRV_FROM_TMM(lchip))
        {
            cmd = DRV_IOR(AutoGenSessionEnCtl_t, AutoGenSessionEnCtl_enBitmap_f);
            CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, &value), ret, error1);
            CTC_BIT_UNSET(value, session_id);
            cmd = DRV_IOW(AutoGenSessionEnCtl_t, AutoGenSessionEnCtl_enBitmap_f);
            CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, &value), ret, error1);
        }
        value = 0;
        cmd = DRV_IOW(AutoGenPktEn_t, AutoGenPktEn_autoGenEn_f);
        CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, session_id, cmd, &value), ret, error1);
        sal_task_sleep(100);/*wait for autoGen rx proc*/
        cmd = DRV_IOW(AutoGenRxProc_t, AutoGenRxProc_autoGenEn_f);
        CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, session_id, cmd, &value), ret, error1);
        cmd = DRV_IOW(AutoGenPktEn_t, AutoGenPktEn_tokenBytesCnt_f);
        CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, session_id, cmd, &value), ret, error1);

        sal_task_sleep(50);
        if (DRV_IS_DUET2(lchip))
        {
            CTC_BIT_UNSET(g_npm_master[lchip]->tx_dmm_en_bitmap, session_id);
            SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_NPM, SYS_WB_APPID_NPM_SUBID_MASTER, 1);
            cmd = DRV_IOW(DsOamExcp_t, DsOamExcp_destMap_f);
            CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, SYS_OAM_EXCP_ETH_DM, cmd, &dest_info.dest_map), ret, error1);
        }
    }
    NPM_UNLOCK(lchip);
    return ret;

    error2:
    if ((modify_dmm_destmap) && DRV_IS_DUET2(lchip))
    {
        cmd = DRV_IOW(DsOamExcp_t, DsOamExcp_destMap_f);
        DRV_FIELD_IOCTL(lchip, SYS_OAM_EXCP_ETH_DM, cmd, &dest_info.dest_map);
    }
    error1:
    NPM_UNLOCK(lchip);
    return ret;
}


int32
sys_usw_npm_get_stats(uint8 lchip, uint32 session_id, ctc_npm_stats_t* p_stats)
{
    uint32 cmd = 0;
    int32 ret = 0;
    AutoGenPktTxPktStats_m tx_stats;
    AutoGenPktRxPktStats_m rx_stats;
    AutoGenPktTxPktAck_m tx_ack;
    uint32 autogen_en = 0;
    uint32 tmp[2] = {0};
    uint32 tmp_rx[2] = {0};
    uint64 total_delay;
    uint64 total_far_delay;
    uint64 tx_pkts;
    uint64 rx_pkts;
    uint64 tx_bytes;
    uint64 rx_bytes;
    uint64 min_delay = 0;
    uint64 max_delay = 0;
    uint64 jitter = 0;
    uint8  is_ntp_mode = 0;
    uint32 tmp_disorder_pkts =0;
    sys_npm_session_t * npm_session = NULL;

    SYS_NPM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    CTC_PTR_VALID_CHECK(p_stats);
    LCHIP_CHECK(lchip);
    SYS_NPM_INIT_CHECK(lchip);
    MCHIP_DMA(lchip)->dma_stats_func(lchip, SYS_DMA_TBL_RD2_CHAN_ID);
    NPM_LOCK(lchip);
    if (MCHIP_NPM(lchip)->get_lite_stats && CTC_NPM_IS_LITE_SESSION(session_id))
    {
        CTC_ERROR_GOTO(MCHIP_NPM(lchip)->get_lite_stats(lchip,session_id,p_stats), ret, error_proc);
        NPM_UNLOCK(lchip);
        return CTC_E_NONE;
    }

    npm_session = _sys_usw_npm_lkup_session(lchip, session_id);
    if (NULL == npm_session)
    {
        NPM_UNLOCK(lchip);
        return CTC_E_NOT_EXIST;
    }

    cmd = DRV_IOR(AutoGenPktEn_t, AutoGenPktEn_autoGenEn_f);
    CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, session_id, cmd, &autogen_en), ret, error_proc);
    p_stats->tx_en = autogen_en ? 1:0;


    /* get AutoGen tx stats */
    if (DRV_IS_DUET2(lchip))
    {
        CTC_ERROR_GOTO(_sys_usw_npm_get_rx_tx_stats(lchip, session_id, 1, (uint32*)&tx_stats), ret, error_proc);
    }
    else
    {
        cmd = DRV_IOR(AutoGenPktTxPktStats_t, DRV_ENTRY_FLAG);
        CTC_ERROR_GOTO(DRV_IOCTL(lchip, session_id, cmd, &tx_stats), ret, error_proc);
    }
    tx_pkts = GetAutoGenPktTxPktStats(V, txPkts_f, &tx_stats);
    (p_stats->clear_en) ? (npm_session->session_stats.tx_pkts_all = tx_pkts) : (npm_session->session_stats.tx_pkts_all += tx_pkts);

    GetAutoGenPktTxPktStats(A, txBytes_f , &tx_stats, &tmp);
    tx_bytes = ((uint64)tmp[1]<<32) + tmp[0];
    (p_stats->clear_en) ? (npm_session->tx_bytes_all = tx_bytes) : (npm_session->tx_bytes_all += tx_bytes);

    /* get AutoGen rx stats */
    if (DRV_IS_DUET2(lchip))
    {
        CTC_ERROR_GOTO(_sys_usw_npm_get_rx_tx_stats(lchip, session_id, 0, (uint32*)&rx_stats), ret, error_proc);
    }
    else
    {
        cmd = DRV_IOR(AutoGenPktRxPktStats_t, DRV_ENTRY_FLAG);
        CTC_ERROR_GOTO(DRV_IOCTL(lchip, session_id, cmd, &rx_stats), ret, error_proc);
    }
    rx_pkts = GetAutoGenPktRxPktStats(V, rxPkts_f, &rx_stats);
    (p_stats->clear_en) ? (npm_session->session_stats.rx_pkts_all = rx_pkts) : (npm_session->session_stats.rx_pkts_all += rx_pkts);

    GetAutoGenPktRxPktStats(A, rxBytes_f , &rx_stats, &tmp_rx);
    rx_bytes = ((uint64)tmp_rx[1]<<32) + tmp_rx[0];
    (p_stats->clear_en) ? (npm_session->rx_bytes_all = rx_bytes) :(npm_session->rx_bytes_all += rx_bytes);

    is_ntp_mode = npm_session->session_stats.is_ntp_ts;
    sal_memset(tmp, 0, sizeof(tmp));
    GetAutoGenPktRxPktStats(A, totalDTs_f , &rx_stats, &tmp);
    /*NTP mode: low 32 bits uint: 1 / 2^32 ns, precision < 0.25 ns*/
    total_delay = is_ntp_mode ? ((uint64)tmp[1]*1000000000 + (uint64)tmp[0]*SYS_NPM_DECIMAL_VALUE_FOR_PRECISION / 10000000000LLU) : (((uint64)tmp[1] << 32) + tmp[0]);
    (p_stats->clear_en) ? (npm_session->session_stats.total_delay_all = total_delay) : (npm_session->session_stats.total_delay_all += total_delay);

    sal_memset(tmp, 0, sizeof(tmp));
    GetAutoGenPktRxPktStats(A, totalDTs2_f , &rx_stats, &tmp);
    total_far_delay = is_ntp_mode ? ((uint64)tmp[1]*1000000000 + (uint64)tmp[0]*SYS_NPM_DECIMAL_VALUE_FOR_PRECISION / 10000000000LLU) : (((uint64)tmp[1] << 32) + tmp[0]);
    (p_stats->clear_en) ? (npm_session->total_far_delay_all = total_far_delay) : (npm_session->total_far_delay_all += total_far_delay);

    p_stats->tx_bytes = npm_session->tx_bytes_all;
    p_stats->tx_pkts = npm_session->session_stats.tx_pkts_all;

    p_stats->rx_pkts = npm_session->session_stats.rx_pkts_all;
    p_stats->rx_bytes = npm_session->rx_bytes_all;

    p_stats->total_delay = npm_session->session_stats.total_delay_all;
    p_stats->total_far_delay = npm_session->total_far_delay_all;
    if (p_stats->total_delay > p_stats->total_far_delay)
    {
        p_stats->total_near_delay = p_stats->total_delay - p_stats->total_far_delay;
    }

    jitter =SYS_NPM_TS_TO_NS(is_ntp_mode, GetAutoGenPktRxPktStats(V, maxJitter_f, &rx_stats));
    npm_session->session_stats.max_jitter = (p_stats->clear_en) ? (jitter) : ((npm_session->session_stats.max_jitter < jitter) ? jitter : npm_session->session_stats.max_jitter);
    p_stats->max_jitter = npm_session->session_stats.max_jitter;

    (p_stats->clear_en) ? (npm_session->session_stats.total_jitter_all = SYS_NPM_TS_TO_NS(is_ntp_mode, GetAutoGenPktRxPktStats(V, totalJitter_f, &rx_stats))):\
		(npm_session->session_stats.total_jitter_all += SYS_NPM_TS_TO_NS(is_ntp_mode, GetAutoGenPktRxPktStats(V, totalJitter_f, &rx_stats)));
    p_stats->total_jitter = npm_session->session_stats.total_jitter_all;

    sal_memset(tmp, 0, sizeof(tmp));
    GetAutoGenPktRxPktStats(A, minDelay_f , &rx_stats, &tmp);
    min_delay = is_ntp_mode ? ((uint64)tmp[1]*1000000000 + (uint64)tmp[0]*SYS_NPM_DECIMAL_VALUE_FOR_PRECISION / 10000000000LLU) : (((uint64)tmp[1] << 32) + tmp[0]);
    jitter = SYS_NPM_TS_TO_NS(is_ntp_mode, GetAutoGenPktRxPktStats(V, minJitter_f, &rx_stats));
    if (min_delay)/*min_delay=0, means stats has been cleared on read*/
    {
        npm_session->session_stats.min_delay = (p_stats->clear_en) ? (min_delay) : ((npm_session->session_stats.min_delay > min_delay) ? min_delay : npm_session->session_stats.min_delay);
        npm_session->session_stats.min_jitter = (p_stats->clear_en) ? (jitter) : ((npm_session->session_stats.min_jitter > jitter) ? jitter : npm_session->session_stats.min_jitter);
    }
    p_stats->min_delay = npm_session->session_stats.min_delay;
    p_stats->min_delay = (SYS_NPM_UINT64_MAX == p_stats->min_delay) ? 0 : p_stats->min_delay;
    p_stats->min_jitter = npm_session->session_stats.min_jitter;
    p_stats->min_jitter = (CTC_MAX_UINT32_VALUE == p_stats->min_jitter) ? 0 : p_stats->min_jitter;

    sal_memset(tmp, 0, sizeof(tmp));
    GetAutoGenPktRxPktStats(A, maxDelay_f , &rx_stats, &tmp);
    max_delay= is_ntp_mode ? ((uint64)tmp[1]*1000000000 + (uint64)tmp[0]*SYS_NPM_DECIMAL_VALUE_FOR_PRECISION / 10000000000LLU) : (((uint64)tmp[1] << 32) + tmp[0]);
    npm_session->session_stats.max_delay = (p_stats->clear_en) ? (max_delay) : ((npm_session->session_stats.max_delay  < max_delay) ? max_delay : npm_session->session_stats.max_delay);
    p_stats->max_delay = npm_session->session_stats.max_delay ;

    sal_memset(tmp, 0, sizeof(tmp));
    GetAutoGenPktRxPktStats(A, lastTs_f , &rx_stats, &tmp);
    if(tmp[0] != 0 || tmp[1] != 0)
    {
        npm_session->session_stats.last_ts = is_ntp_mode ? ((uint64)tmp[1]*1000000000 + (uint64)tmp[0]*SYS_NPM_DECIMAL_VALUE_FOR_PRECISION / 10000000000LLU) : ((uint64)tmp[1]*1000000000 + tmp[0]);
    }
    p_stats->last_ts = npm_session->session_stats.last_ts;

    /* get AutoGen txAck stats */
    cmd = DRV_IOR(AutoGenPktTxPktAck_t, DRV_ENTRY_FLAG);
    CTC_ERROR_GOTO(DRV_IOCTL(lchip, session_id, cmd, &tx_ack), ret, error_proc);
    sal_memset(tmp, 0, sizeof(tmp));
    GetAutoGenPktTxPktAck(A, firstTs_f , &tx_ack, &tmp);
    if (!npm_session->session_stats.is_ntp_ts)
    {
        p_stats->first_ts = (uint64)tmp[1]*1000000000 + tmp[0];
    }
    else
    {
        p_stats->first_ts = (uint64)tmp[1]*1000000000 + (uint64)tmp[0]*SYS_NPM_DECIMAL_VALUE_FOR_PRECISION / 10000000000LLU;
    }

    tmp_disorder_pkts = GetAutoGenPktTxPktAck(V, seqDisorderCnt_f , &tx_ack);
    if (p_stats->clear_en)
    {
        npm_session->session_stats.disorder_pkts = (npm_session->last_disorder_pkts > tmp_disorder_pkts) ? (tmp_disorder_pkts + 0x10000 - npm_session->last_disorder_pkts )
        : (tmp_disorder_pkts - npm_session->last_disorder_pkts);
    }
    else
    {
        npm_session->session_stats.disorder_pkts += (npm_session->last_disorder_pkts > tmp_disorder_pkts) ? (tmp_disorder_pkts + 0x10000 - npm_session->last_disorder_pkts )
        : (tmp_disorder_pkts - npm_session->last_disorder_pkts);
    }
    npm_session->last_disorder_pkts = tmp_disorder_pkts;

    if (GetAutoGenPktTxPktAck(V, measureType_f , &tx_ack) == 0)
    {
        p_stats->far_end_jitter[0] = p_stats->max_jitter;
        p_stats->far_end_jitter[1] = p_stats->min_jitter;
        p_stats->far_end_jitter[2] = p_stats->total_jitter;
    }
    else if (GetAutoGenPktTxPktAck(V, measureType_f , &tx_ack) == 1)
    {
        p_stats->near_end_jitter[0] = p_stats->max_jitter;
        p_stats->near_end_jitter[1] = p_stats->min_jitter;
        p_stats->near_end_jitter[2] = p_stats->total_jitter;
    }

    p_stats->disorder_pkts = npm_session->session_stats.disorder_pkts;
    p_stats->ir[0]= npm_session->max_rx_ir;
    p_stats->ir[1]= (npm_session->min_rx_ir==SYS_NPM_UINT64_MAX)?0:npm_session->min_rx_ir;
    p_stats->ses_cnt[0] = npm_session->ses_cnt;
    p_stats->ses_cnt[1] = npm_session->non_ses_cnt;
    p_stats->seconds = npm_session->seconds;
    p_stats->in_avl_period = npm_session->in_avl_period;
    p_stats->avl_periods[0] = npm_session->avl_periods;
    p_stats->avl_periods[1] = npm_session->unavl_periods;
    p_stats->tx_fcf = GetAutoGenPktTxPktAck(V, txSeqNum_f , &tx_ack);
    p_stats->tx_fcb = GetAutoGenPktTxPktAck(V, txFcb_f , &tx_ack);
    p_stats->rx_fcl = GetAutoGenPktTxPktAck(V, rxFcl_f , &tx_ack);
error_proc:
    NPM_UNLOCK(lchip);
    return ret;

}


int32
sys_usw_npm_clear_stats(uint8 lchip, uint32 session_id)
{
    int32 ret = 0;

    SYS_NPM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    LCHIP_CHECK(lchip);
    SYS_NPM_INIT_CHECK(lchip);
    MCHIP_DMA(lchip)->dma_stats_func(lchip, SYS_DMA_TBL_RD2_CHAN_ID);
    NPM_LOCK(lchip);
    ret = _sys_usw_npm_clear_stats( lchip,  session_id);
    NPM_UNLOCK(lchip);
    return ret;
}

int32
sys_usw_npm_set_global_config(uint8 lchip, ctc_npm_global_cfg_t* p_npm)
{
    uint32 cmd = 0;
    int32 ret = 0;
    AutoGenPktGlbCtl_m glb_ctl;
    uint32 value = 0;
    uint8 index = 0;
    uint8 loop = 0;
    uint32 field_id = 0;
    uint32 autogen_en = 0;

    SYS_NPM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_NPM_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_npm);
    CTC_MAX_VALUE_CHECK(p_npm->session_mode, CTC_NPM_SESSION_MODE_4);

    sal_memset(&glb_ctl, 0, sizeof(AutoGenPktGlbCtl_m));

    NPM_LOCK(lchip);
    cmd = DRV_IOR(AutoGenPktEn_t, AutoGenPktEn_autoGenEn_f);
    for (loop = 0; loop < MCHIP_CAP(SYS_CAP_NPM_SESSION_NUM); loop++)
    {
        CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, loop, cmd, &autogen_en), ret, error_proc);
        if (autogen_en)
        {
            ret = CTC_E_HW_BUSY;
            goto error_proc;
        }
    }
    cmd = DRV_IOR(AutoGenPktGlbCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_GOTO(DRV_IOCTL(lchip, 0, cmd, &glb_ctl), ret, error_proc);
    switch (p_npm->session_mode)
    {
        case CTC_NPM_SESSION_MODE_8:
            value = 0;
            break;
        case CTC_NPM_SESSION_MODE_6:
            value = 1;
            break;
        case CTC_NPM_SESSION_MODE_4:
            value = 2;
            if (DRV_FROM_TMM(lchip))
            {
                ret = CTC_E_NOT_SUPPORT;
                goto error_proc;
            }
            break;
        default:
            ret = CTC_E_INVALID_PARAM;
            goto error_proc;
    }
    SetAutoGenPktGlbCtl(V, sessionMode_f, &glb_ctl, value);


    for (index = 0; index < CTC_NPM_MAX_EMIX_NUM; index++)
    {
        field_id = AutoGenPktGlbCtl_g_0_size_f + index;
        value = p_npm->emix_size[index];
        if (value && (value < SYS_NPM_MIN_TOTAL_PACKET_SIZE) )
        {
            ret = CTC_E_INVALID_PARAM;
            goto error_proc;
        }
        SYS_MAX_VALUE_CHECK_WITH_UNLOCK(value,MCHIP_CAP(SYS_CAP_PORT_MAX_FRAMESIZE_MAX_VALUE),g_npm_master[lchip]->npm_mutex);
        drv_set_field(lchip, AutoGenPktGlbCtl_t, field_id, &glb_ctl, &value);
    }

    cmd = DRV_IOW(AutoGenPktGlbCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_GOTO(DRV_IOCTL(lchip, 0, cmd, &glb_ctl), ret, error_proc);

    error_proc:
    NPM_UNLOCK(lchip);
    return ret;
}

int32
sys_usw_npm_get_global_config(uint8 lchip, ctc_npm_global_cfg_t* p_npm)
{
    uint32 cmd = 0;
    AutoGenPktGlbCtl_m glb_ctl;
    uint8 index = 0;
    uint32 field_id = 0;
    uint32 value = 0;
    int32 ret = 0;

    SYS_NPM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    CTC_PTR_VALID_CHECK(p_npm);
    SYS_NPM_INIT_CHECK(lchip);
    sal_memset(&glb_ctl, 0, sizeof(AutoGenPktGlbCtl_m));

    NPM_LOCK(lchip);
    cmd = DRV_IOR(AutoGenPktGlbCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_GOTO(DRV_IOCTL(lchip, 0, cmd, &glb_ctl), ret, error_proc);
    p_npm->session_mode = GetAutoGenPktGlbCtl(V, sessionMode_f, &glb_ctl);

    for (index = 0; index < CTC_NPM_MAX_EMIX_NUM; index++)
    {
        field_id = AutoGenPktGlbCtl_g_0_size_f + index;
        drv_get_field(lchip, AutoGenPktGlbCtl_t, field_id, &glb_ctl, &value);
        p_npm->emix_size[index] = value;
    }

error_proc:
    NPM_UNLOCK(lchip);
    return ret;
}


STATIC int32
_sys_usw_npm_wb_session_mapping_info(sys_wb_npm_session_t*p_wb_session, sys_npm_session_t* p_session, uint8 sync)
{
    if (sync)
    {
        p_wb_session->session_id = p_session->session_id;
        p_wb_session->mep_idx = p_session->mep_idx;
        p_wb_session->is_ntp_ts = p_session->session_stats.is_ntp_ts;
        p_wb_session->flr_for_ses = p_session->flr_for_ses;
        p_wb_session->avl_period_thrd = p_session->avl_period_thrd;
        p_wb_session->rsv = 0;
    }
    else
    {
        p_session->session_id = p_wb_session->session_id;
        p_session->mep_idx = p_wb_session->mep_idx;
        p_session->in_avl_period = 1;
        p_session->flr_for_ses = p_wb_session->flr_for_ses;
        p_session->avl_period_thrd = p_wb_session->avl_period_thrd;
        p_session->seconds = 0;
        p_session->max_rx_ir = 0;
        p_session->min_rx_ir = SYS_NPM_UINT64_MAX;
        p_session->avl_periods = 0;
        p_session->unavl_periods = 0;
        p_session->session_stats.min_delay = SYS_NPM_UINT64_MAX;
        p_session->session_stats.min_jitter = CTC_MAX_UINT32_VALUE;
        p_session->session_stats.is_ntp_ts = p_wb_session->is_ntp_ts;
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_npm_wb_session_lite_mapping_info(sys_wb_npm_session_lite_t*p_wb_session_lite, sys_npm_lite_session_t* p_session_lite, uint8 sync)
{
    if (sync)
    {
        p_wb_session_lite->session_id = p_session_lite->session_id;
        p_wb_session_lite->mep_idx = p_session_lite->mep_idx;
        p_wb_session_lite->twamp_idx = p_session_lite->twamp_idx;
        p_wb_session_lite->ma_idx = p_session_lite->ma_idx;
        p_wb_session_lite->ts_format = p_session_lite->ts_format;
        p_wb_session_lite->mode = p_session_lite->mode;
        p_wb_session_lite->is_twamp = p_session_lite->is_twamp;
        p_wb_session_lite->is_ipv6 = p_session_lite->is_ipv6;
        p_wb_session_lite->rsv = 0;
    }
    else
    {
        p_session_lite->session_id = p_wb_session_lite->session_id;
        p_session_lite->mep_idx = p_wb_session_lite->mep_idx;
        p_session_lite->twamp_idx = p_wb_session_lite->twamp_idx;
        p_session_lite->ma_idx = p_wb_session_lite->ma_idx;
        p_session_lite->ts_format = p_wb_session_lite->ts_format;
        p_session_lite->mode = p_wb_session_lite->mode;
        p_session_lite->is_twamp = p_wb_session_lite->is_twamp;
        p_session_lite->is_ipv6 = p_wb_session_lite->is_ipv6;
        p_session_lite->session_stats.min_delay = SYS_NPM_UINT64_MAX;
        p_session_lite->lite_stats.two_way_min_jitter= CTC_MAX_UINT32_VALUE;
        p_session_lite->lite_stats.far_min_jitter = CTC_MAX_UINT32_VALUE;
        p_session_lite->lite_stats.near_min_jitter = CTC_MAX_UINT32_VALUE;
        p_session_lite->is_npm =1;
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_npm_sync_session_vector_func(sys_npm_session_t* p_session, void *user_data)
{
   uint32 max_entry_cnt = 0;
   sys_wb_npm_session_t* p_wb_session = NULL;
   ctc_wb_data_t *wb_data = (ctc_wb_data_t *)(user_data);

   max_entry_cnt = wb_data->buffer_len / (wb_data->key_len + wb_data->data_len);
   p_wb_session = (sys_wb_npm_session_t *)wb_data->buffer + wb_data->valid_cnt;
   sal_memset(p_wb_session, 0, sizeof(sys_wb_npm_session_t));
   CTC_ERROR_RETURN(_sys_usw_npm_wb_session_mapping_info(p_wb_session, p_session, 1));
   if (++wb_data->valid_cnt == max_entry_cnt)
   {
       CTC_ERROR_RETURN(ctc_wb_add_entry(wb_data));
       wb_data->valid_cnt = 0;
   }
   return CTC_E_NONE;
}

STATIC int32
_sys_usw_npm_sync_session_lite_vector_func(sys_npm_lite_session_t* p_session_lite, void *user_data)
{
   uint32 max_entry_cnt = 0;
   sys_wb_npm_session_lite_t* p_wb_session_lite = NULL;
   ctc_wb_data_t *wb_data = (ctc_wb_data_t *)(user_data);

   max_entry_cnt = wb_data->buffer_len / (wb_data->key_len + wb_data->data_len);
   p_wb_session_lite = (sys_wb_npm_session_lite_t *)wb_data->buffer + wb_data->valid_cnt;
   sal_memset(p_wb_session_lite, 0, sizeof(sys_wb_npm_session_lite_t));
   CTC_ERROR_RETURN(_sys_usw_npm_wb_session_lite_mapping_info(p_wb_session_lite, p_session_lite, 1));
   if (++wb_data->valid_cnt == max_entry_cnt)
   {
       CTC_ERROR_RETURN(ctc_wb_add_entry(wb_data));
       wb_data->valid_cnt = 0;
   }
   return CTC_E_NONE;
}

int32
_sys_usw_npm_wb_init(uint8 lchip)
{
    ctc_wb_appid_t  appid;
    sal_memset(&appid,0,sizeof(appid));

    appid.app_id = lchip << 16 | CTC_WB_APPID(CTC_FEATURE_NPM, SYS_WB_APPID_NPM_SUBID_MASTER) ;
    appid.entry_num = SYS_WB_FEATURE_MASTER_NUM;
    appid.entry_size  = sizeof(sys_wb_npm_master_t);
    appid.rt_en = 0;
    ctc_wb_add_appid(lchip, &appid);

    appid.app_id = lchip << 16 | CTC_WB_APPID(CTC_FEATURE_NPM, SYS_WB_APPID_NPM_SUBID_SESSION) ;
    appid.entry_num = MCHIP_CAP(SYS_CAP_NPM_SESSION_NUM);
    appid.entry_size  = sizeof(sys_wb_npm_session_t);
    appid.rt_en = 0;
    ctc_wb_add_appid(lchip, &appid);

    if (DRV_FROM_TMM(lchip))
    {
        appid.app_id = lchip << 16 | CTC_WB_APPID(CTC_FEATURE_NPM, SYS_WB_APPID_NPM_SUBID_SESSION_LITE) ;
        appid.entry_num = DRV_TABLE_MAX_INDEX(lchip, DsOamTwampCfg_t);
        appid.entry_size  = sizeof(sys_wb_npm_session_lite_t);
        appid.rt_en = 0;
        ctc_wb_add_appid(lchip, &appid);
    }

    /*npm im appid init*/
    CTC_ERROR_RETURN(sys_usw_npm_im_wb_init(lchip));

    return CTC_E_NONE;
}

int32
sys_usw_npm_wb_sync(uint8 lchip, uint32 app_id)
{
    int32 ret = CTC_E_NONE;
    ctc_wb_data_t wb_data = {0};
    sys_wb_npm_master_t* p_wb_npm_master = NULL;
    SYS_NPM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    CTC_WB_ALLOC_BUFFER(&wb_data.buffer);
    NPM_LOCK(lchip);
    if (app_id == 0 || CTC_WB_SUBID(app_id) == SYS_WB_APPID_NPM_SUBID_MASTER)
    {
        /*sync master*/
        CTC_WB_INIT_DATA_T((&wb_data), sys_wb_npm_master_t, CTC_FEATURE_NPM, SYS_WB_APPID_NPM_SUBID_MASTER);

        p_wb_npm_master = (sys_wb_npm_master_t*)wb_data.buffer;

        p_wb_npm_master->config_dmm_bitmap = g_npm_master[lchip]->config_dmm_bitmap;
        p_wb_npm_master->tx_dmm_en_bitmap = g_npm_master[lchip]->tx_dmm_en_bitmap;
        p_wb_npm_master->lchip = lchip;
        p_wb_npm_master->version = SYS_WB_VERSION_NPM;
        p_wb_npm_master->ecpu_npm_im_en = g_npm_master[lchip]->ecpu_npm_im_en;
        sal_memcpy(p_wb_npm_master->src_node_fp_id, g_npm_master[lchip]->src_node_fp_id, sizeof(g_npm_master[lchip]->src_node_fp_id));
        sal_memcpy(p_wb_npm_master->src_node_delay_fp_id, g_npm_master[lchip]->src_node_delay_fp_id, sizeof(g_npm_master[lchip]->src_node_delay_fp_id));
        sal_memcpy(p_wb_npm_master->sink_node_fp_id, g_npm_master[lchip]->sink_node_fp_id, sizeof(g_npm_master[lchip]->sink_node_fp_id));
        wb_data.valid_cnt = 1;
        CTC_ERROR_GOTO(ctc_wb_add_entry(&wb_data), ret, done);
        CTC_WB_SYNC_END_DATA(CTC_FEATURE_NPM, SYS_WB_APPID_NPM_SUBID_MASTER);
    }

    if (app_id == 0 || CTC_WB_SUBID(app_id) == SYS_WB_APPID_NPM_SUBID_SESSION)
    {
        /*sync session*/
        CTC_WB_INIT_DATA_T((&wb_data), sys_wb_npm_session_t, CTC_FEATURE_NPM, SYS_WB_APPID_NPM_SUBID_SESSION);
        wb_data.valid_cnt = 0;
        CTC_ERROR_GOTO(ctc_vector_traverse(g_npm_master[lchip]->session, (vector_traversal_fn)_sys_usw_npm_sync_session_vector_func, (void*)&wb_data), ret, done);
        if (wb_data.valid_cnt > 0)
        {
            CTC_ERROR_GOTO(ctc_wb_add_entry(&wb_data), ret, done);
            wb_data.valid_cnt = 0;
        }
        CTC_WB_SYNC_END_DATA(CTC_FEATURE_NPM, SYS_WB_APPID_NPM_SUBID_SESSION);
    }
    if ((app_id == 0 || CTC_WB_SUBID(app_id) == SYS_WB_APPID_NPM_SUBID_SESSION_LITE)&& DRV_FROM_TMM(lchip))
    {
         /*sync session lite*/
        CTC_WB_INIT_DATA_T((&wb_data), sys_wb_npm_session_lite_t, CTC_FEATURE_NPM, SYS_WB_APPID_NPM_SUBID_SESSION_LITE);
        wb_data.valid_cnt = 0;
        CTC_ERROR_GOTO(ctc_vector_traverse(g_npm_master[lchip]->session_lite, (vector_traversal_fn)_sys_usw_npm_sync_session_lite_vector_func, (void *)&wb_data), ret, done);
        if (wb_data.valid_cnt > 0)
        {
            CTC_ERROR_GOTO(ctc_wb_add_entry(&wb_data), ret, done);
            wb_data.valid_cnt = 0;
        }
        CTC_WB_SYNC_END_DATA(CTC_FEATURE_NPM, SYS_WB_APPID_NPM_SUBID_SESSION_LITE);
    }

    CTC_ERROR_GOTO(sys_usw_npm_im_wb_sync(lchip, app_id), ret, done);
done:
    NPM_UNLOCK(lchip);
    CTC_WB_FREE_BUFFER(wb_data.buffer);

    return ret;
}

int32
sys_usw_npm_wb_restore(uint8 lchip)
{
    int32 ret = CTC_E_NONE;
    ctc_wb_query_t    wb_query;
    sys_wb_npm_master_t wb_npm_master = {0};
    sys_wb_npm_session_t wb_session = {0};
    sys_wb_npm_session_lite_t wb_session_lite = {0};
    sys_npm_session_t* p_session = NULL;
    sys_npm_lite_session_t* p_session_lite = NULL;
    uint32 entry_cnt = 0;
    sys_usw_opf_t opf;
    uint32 cmd = 0;
    uint32 field_val = 0;

    SYS_NPM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    /*restore master*/
    CTC_WB_ALLOC_BUFFER(&wb_query.buffer);

    CTC_WB_INIT_QUERY_T((&wb_query),sys_wb_npm_master_t, CTC_FEATURE_NPM, SYS_WB_APPID_NPM_SUBID_MASTER);

    CTC_ERROR_GOTO(ctc_wb_query_entry(&wb_query), ret, done);
    if (wb_query.valid_cnt != 1 || wb_query.is_end != 1)
    {
        CTC_WB_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "query npm master error! valid_cnt: %u, is_end: %d.\n", wb_query.valid_cnt, wb_query.is_end);
        ret = CTC_E_NONE;
        goto done;
    }

    sal_memcpy((uint8*)&wb_npm_master, (uint8*)wb_query.buffer, wb_query.key_len + wb_query.data_len);

    if (CTC_WB_VERSION_CHECK(SYS_WB_VERSION_NPM, wb_npm_master.version))
    {
        ret = CTC_E_VERSION_MISMATCH;
        goto done;
    }

    g_npm_master[lchip]->config_dmm_bitmap = wb_npm_master.config_dmm_bitmap;
    g_npm_master[lchip]->tx_dmm_en_bitmap = wb_npm_master.tx_dmm_en_bitmap;
    g_npm_master[lchip]->ecpu_npm_im_en = wb_npm_master.ecpu_npm_im_en;
    sal_memcpy(g_npm_master[lchip]->src_node_fp_id, wb_npm_master.src_node_fp_id, sizeof(g_npm_master[lchip]->src_node_fp_id));
    sal_memcpy(g_npm_master[lchip]->src_node_delay_fp_id, wb_npm_master.src_node_delay_fp_id, sizeof(g_npm_master[lchip]->src_node_delay_fp_id));
    sal_memcpy(g_npm_master[lchip]->sink_node_fp_id, wb_npm_master.sink_node_fp_id, sizeof(g_npm_master[lchip]->sink_node_fp_id));
    cmd = DRV_IOR(ParserMplsCtl_t, ParserMplsCtl_supportMplsInbandOam_f);
    DRV_FIELD_IOCTL(lchip, 0, cmd, &field_val);
    if (field_val)
    {
        sys_usw_npm_im_set_flow_en(lchip, CTC_NPM_IM_TYPE_MPLS, TRUE);
    }
    /*restore session*/
    CTC_WB_INIT_QUERY_T((&wb_query), sys_wb_npm_session_t, CTC_FEATURE_NPM, SYS_WB_APPID_NPM_SUBID_SESSION);
    CTC_WB_QUERY_ENTRY_BEGIN((&wb_query));
    sal_memcpy((uint8*)&wb_session, (uint8*)(wb_query.buffer) + entry_cnt * (wb_query.key_len + wb_query.data_len), wb_query.key_len + wb_query.data_len);
    entry_cnt++;

    p_session = mem_malloc(MEM_NPM_MODULE, sizeof(sys_npm_session_t));
    if (NULL == p_session)
    {
        ret = CTC_E_NO_MEMORY;
        goto done;
    }
    sal_memset(p_session, 0, sizeof(sys_npm_session_t));
    CTC_ERROR_GOTO(_sys_usw_npm_wb_session_mapping_info(&wb_session, p_session, 0), ret, done);

    if (FALSE == ctc_vector_add(g_npm_master[lchip]->session, p_session->session_id, p_session))
    {
        mem_free(p_session);
        ret = CTC_E_NO_MEMORY;
        goto done;
    }
    CTC_WB_QUERY_ENTRY_END((&wb_query));

    if(DRV_FROM_TMM(lchip))
    {
        /*restore session lite*/
        CTC_WB_INIT_QUERY_T((&wb_query), sys_wb_npm_session_lite_t, CTC_FEATURE_NPM, SYS_WB_APPID_NPM_SUBID_SESSION_LITE);
        CTC_WB_QUERY_ENTRY_BEGIN((&wb_query));
        sal_memcpy((uint8*)&wb_session_lite, (uint8*)(wb_query.buffer) + entry_cnt * (wb_query.key_len + wb_query.data_len), wb_query.key_len + wb_query.data_len);
        entry_cnt++;
        p_session_lite = mem_malloc(MEM_NPM_MODULE, sizeof(sys_npm_lite_session_t));
        if (NULL == p_session_lite)
        {
            ret = CTC_E_NO_MEMORY;
            goto done;
        }
        sal_memset(p_session_lite, 0, sizeof(sys_npm_lite_session_t));
        CTC_ERROR_GOTO(_sys_usw_npm_wb_session_lite_mapping_info(&wb_session_lite, p_session_lite, 0), ret, done);
        if (FALSE == ctc_vector_add(g_npm_master[lchip]->session_lite, SYS_NPM_LITE_SESSION_CONVERT(p_session_lite->session_id), p_session_lite))
        {
            ret = CTC_E_NO_MEMORY;
            goto done;
        }
        opf.pool_type = g_npm_master[lchip]->npm_opf_type;
        opf.pool_index  = SYS_NPM_OPF_TYPE_DMM_TWAMP_LITE;
        CTC_ERROR_GOTO(sys_usw_opf_alloc_offset_from_position(lchip, &opf, 1, p_session_lite->twamp_idx), ret, done);
        if(p_session_lite->is_twamp)
        {
            CTC_ERROR_GOTO(sys_usw_oam_wb_restore_npm_lite(lchip, p_session_lite), ret, done);
        }
        CTC_WB_QUERY_ENTRY_END((&wb_query));
    }
    CTC_WB_FREE_BUFFER(wb_query.buffer);

    CTC_ERROR_RETURN(sys_usw_npm_im_wb_restore(lchip));
    return ret;
done:
    CTC_WB_FREE_BUFFER(wb_query.buffer);

    if (p_session_lite)
    {
        mem_free(p_session_lite);
    }

    return ret;
}

int32
sys_usw_npm_show_status(uint8 lchip)
{
    int32 ret = 0;
    uint32 loop = 0;
    uint32 cmd = 0;
    uint32 autogen_en = 0;
    uint16 session_count = 0;
    sys_npm_lite_session_t* npm_lite_session = NULL;
    ctc_npm_cfg_t cfg;
    char* PATTEN_TYPE_STR[8] =
    {
        "Repeat", "Pbrs", "Inc_byte",
        "Dec_byte", "Inc_word", "Dec_word"
    };

    char* PKT_SIZE_MODE_STR[5] =
    {
        "Fix", "Increase", "Emix"
    };

    char* TX_MODE_STR[5] =
    {
        "Continuous", "Stop after fix num", "Stop after fix time"
    };

    char* MEASURE_TYPE[3] =
    {
        "Far End", "Near End", "Two way/All"
    };
        char* DM_TYPE[2] =
    {
        "DMM", "1DM"
    };
    sal_memset(&cfg, 0, sizeof(cfg));

    SYS_NPM_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_NPM_INIT_CHECK(lchip);

    NPM_LOCK(lchip);
    for (loop = 0; loop < MCHIP_CAP(SYS_CAP_NPM_SESSION_NUM); loop++)
    {
        cmd = DRV_IOR(AutoGenPktEn_t, AutoGenPktEn_autoGenEn_f);
        CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, loop, cmd, &autogen_en), ret, error_proc);
        if (autogen_en)
        {
            cfg.session_id = loop;
            ret = _sys_usw_npm_show_session_status(lchip, &cfg);
            if (ret < 0)
            {
                goto error_proc;
            }
            session_count ++;
            SYS_NPM_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "\nNPM Session %u\n", loop);
            SYS_NPM_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "---------------------------------------------------\n");
            SYS_NPM_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " --%-32s :%u \n", "IPG", cfg.pkt_format.ipg);
            SYS_NPM_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " --%-32s :%s \n", "Tx-mode", TX_MODE_STR[cfg.tx_mode]);
            SYS_NPM_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " --%-32s :%s \n", "Pkt-size-mode", PKT_SIZE_MODE_STR[cfg.pkt_format.frame_size_mode]);
            SYS_NPM_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " --%-32s :%s \n", "Payload pattern type", PATTEN_TYPE_STR[cfg.pkt_format.pattern_type]);
        }
    }
    sal_memset(&cfg, 0, sizeof(cfg));
    autogen_en = 0;
    for (loop = 0; loop < CTC_NPM_LITE_SESSION_NUM; loop++)
    {
        npm_lite_session = (sys_npm_lite_session_t*)ctc_vector_get(g_npm_master[lchip]->session_lite, loop);
        if (NULL == npm_lite_session)
        {
            continue;
        }
        cmd = DRV_IOR(DsOamTwampTxCfg_t, DsOamTwampTxCfg_periodTestEn_f);
        CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, npm_lite_session->twamp_idx, cmd, &autogen_en), ret, error_proc);
        if (autogen_en)
        {
            cfg.session_id = loop;
             ret = _sys_usw_npm_show_lite_session_status(lchip, &cfg);
            session_count ++;
            SYS_NPM_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "\nNPM LITE Session %u\n", loop );
            SYS_NPM_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "---------------------------------------------------\n");
            if (npm_lite_session && npm_lite_session->is_twamp)
            {
                SYS_NPM_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " --%-32s :%u pps\n", "Rate", cfg.rate * SYS_NPM_TX_INTERVAL_TO_PPS);
            }
            else
            {
                SYS_NPM_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " --%-32s :%s \n", "TxDm-Type", DM_TYPE[cfg.lite_cfg.dm_tx_type]);
            }
            SYS_NPM_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " --%-32s :%s \n", "Measure-Type", MEASURE_TYPE[cfg.dm_stats_mode]);

        }
    }
    SYS_NPM_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "\nTotal NPM Session number :%u\n", session_count);

error_proc:
    NPM_UNLOCK(lchip);
    return ret;
}

int32
sys_usw_npm_dump_db(uint8 lchip, sal_file_t p_f,ctc_global_dump_db_t* p_dump_param)
{
    int32 ret = CTC_E_NONE;
    uint32 loop = 0;
    uint32 valid_count = 0;
    sys_npm_session_t * npm_session = NULL;
    SYS_NPM_INIT_CHECK(lchip);
    LCHIP_CHECK(lchip);

    NPM_LOCK(lchip);
    SYS_DUMP_DB_LOG(p_f, "%s\n", "# NPM");
    SYS_DUMP_DB_LOG(p_f, "%s\n", "{");
    SYS_DUMP_DB_LOG(p_f, "%s\n", "Master config:");
    if (DRV_IS_DUET2(lchip))
    {
        SYS_DUMP_DB_LOG(p_f, "%-30s:0x%x\n","config_dmm_bitmap", g_npm_master[lchip]->config_dmm_bitmap);
        SYS_DUMP_DB_LOG(p_f, "%-30s:0x%x\n","tx_dmm_en_bitmap", g_npm_master[lchip]->tx_dmm_en_bitmap);
    }
    SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n","npm im ecpu enable", g_npm_master[lchip]->ecpu_npm_im_en);
    SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n","src_node_fp_id[SYS_IM_TYPE_IPV4]", g_npm_master[lchip]->src_node_fp_id[SYS_IM_TYPE_IPV4]);
    SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n","src_node_fp_id[SYS_IM_TYPE_IPV6]", g_npm_master[lchip]->src_node_fp_id[SYS_IM_TYPE_IPV6]);
    SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n","src_node_fp_id[SYS_IM_TYPE_VXLAN_IPV4]", g_npm_master[lchip]->src_node_fp_id[SYS_IM_TYPE_VXLAN_IPV4]);
    SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n","src_node_fp_id[SYS_IM_TYPE_VXLAN_IPV6]", g_npm_master[lchip]->src_node_fp_id[SYS_IM_TYPE_VXLAN_IPV6]);
    SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n","src_node_delay_fp_id[SYS_IM_TYPE_IPV4]", g_npm_master[lchip]->src_node_delay_fp_id[SYS_IM_TYPE_IPV4]);
    SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n","src_node_delay_fp_id[SYS_IM_TYPE_IPV6]", g_npm_master[lchip]->src_node_delay_fp_id[SYS_IM_TYPE_IPV6]);
    SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n","src_node_delay_fp_id[SYS_IM_TYPE_VXLAN_IPV4]", g_npm_master[lchip]->src_node_delay_fp_id[SYS_IM_TYPE_VXLAN_IPV4]);
    SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n","src_node_delay_fp_id[SYS_IM_TYPE_VXLAN_IPV6]", g_npm_master[lchip]->src_node_delay_fp_id[SYS_IM_TYPE_VXLAN_IPV6]);
    SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n","sink_node_fp_id[SYS_IM_TYPE_IPV4]", g_npm_master[lchip]->sink_node_fp_id[SYS_IM_TYPE_IPV4]);
    SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n","sink_node_fp_id[SYS_IM_TYPE_IPV6]", g_npm_master[lchip]->sink_node_fp_id[SYS_IM_TYPE_IPV6]);
    SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n","sink_node_fp_id[SYS_IM_TYPE_VXLAN_IPV4]", g_npm_master[lchip]->sink_node_fp_id[SYS_IM_TYPE_VXLAN_IPV4]);
    SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n","sink_node_fp_id[SYS_IM_TYPE_VXLAN_IPV6]", g_npm_master[lchip]->sink_node_fp_id[SYS_IM_TYPE_VXLAN_IPV6]);
    SYS_DUMP_DB_LOG(p_f, "%-30s:%u\n","ip im protocl", g_npm_master[lchip]->im_protocol);
    SYS_DUMP_DB_LOG(p_f, "%-30s:","total_delay_all");
    for(loop = 0; loop < MCHIP_CAP(SYS_CAP_NPM_SESSION_NUM); loop++)
    {
        npm_session=_sys_usw_npm_lkup_session(lchip,loop);
        if (NULL == npm_session)
        {
            continue;
        }
        if (0 == npm_session->session_stats.total_delay_all)
        {
            continue;
        }
        SYS_DUMP_DB_LOG(p_f, "[%u:%"PRIu64"]", loop, npm_session->session_stats.total_delay_all);
        if (valid_count % 4 == 3)
        {
            SYS_DUMP_DB_LOG(p_f, "\n%31s", " ");
        }
        valid_count ++;
    }
    SYS_DUMP_DB_LOG(p_f, "\n");

    SYS_DUMP_DB_LOG(p_f, "%-30s:","total_far_delay_all");
    valid_count = 0;
    for(loop = 0; loop < MCHIP_CAP(SYS_CAP_NPM_SESSION_NUM); loop++)
    {
        npm_session = _sys_usw_npm_lkup_session(lchip, loop);
        if (NULL == npm_session)
        {
            continue;
        }
        if (0 == npm_session->total_far_delay_all)
        {
            continue;
        }
        SYS_DUMP_DB_LOG(p_f, "[%u:%"PRIu64"]", loop, npm_session->total_far_delay_all);
        if (valid_count % 4 == 3)
        {
            SYS_DUMP_DB_LOG(p_f, "\n%31s", " ");
        }
        valid_count ++;
    }
    SYS_DUMP_DB_LOG(p_f, "\n");

    SYS_DUMP_DB_LOG(p_f, "%-30s:","tx_pkts_all");
    valid_count = 0;
    for(loop = 0; loop < MCHIP_CAP(SYS_CAP_NPM_SESSION_NUM); loop++)
    {
        npm_session = _sys_usw_npm_lkup_session(lchip, loop);
        if (NULL == npm_session)
        {
            continue;
        }
        if (0 == npm_session->session_stats.tx_pkts_all)
        {
            continue;
        }
        SYS_DUMP_DB_LOG(p_f, "[%u:%"PRIu64"]", loop, npm_session->session_stats.tx_pkts_all);
        if (valid_count % 4 == 3)
        {
            SYS_DUMP_DB_LOG(p_f, "\n%31s", " ");
        }
        valid_count ++;
    }
    SYS_DUMP_DB_LOG(p_f, "\n");

    SYS_DUMP_DB_LOG(p_f, "%-30s:","rx_pkts_all");
    valid_count = 0;
    for(loop = 0; loop < MCHIP_CAP(SYS_CAP_NPM_SESSION_NUM); loop++)
    {
        npm_session = _sys_usw_npm_lkup_session(lchip, loop);
        if (NULL == npm_session)
        {
            continue;
        }
        if (0 == npm_session->session_stats.rx_pkts_all)
        {
            continue;
        }
        SYS_DUMP_DB_LOG(p_f, "[%u:%"PRIu64"]", loop, npm_session->session_stats.rx_pkts_all);
        if (valid_count % 4 == 3)
        {
            SYS_DUMP_DB_LOG(p_f, "\n%31s", " ");
        }
        valid_count ++;
    }
    SYS_DUMP_DB_LOG(p_f, "\n");

    SYS_DUMP_DB_LOG(p_f, "%-30s:","tx_bytes_all");
    valid_count = 0;
    for(loop = 0; loop < MCHIP_CAP(SYS_CAP_NPM_SESSION_NUM); loop++)
    {
        npm_session = _sys_usw_npm_lkup_session(lchip, loop);
        if (NULL == npm_session)
        {
            continue;
        }
        if (0 == npm_session->tx_bytes_all)
        {
            continue;
        }
        SYS_DUMP_DB_LOG(p_f, "[%u:%"PRIu64"]", loop, npm_session->tx_bytes_all);
        if (valid_count % 4 == 3)
        {
            SYS_DUMP_DB_LOG(p_f, "\n%31s", " ");
        }
        valid_count ++;
    }
    SYS_DUMP_DB_LOG(p_f, "\n");

    SYS_DUMP_DB_LOG(p_f, "%-30s:","rx_bytes_all");
    valid_count = 0;
    for(loop = 0; loop < MCHIP_CAP(SYS_CAP_NPM_SESSION_NUM); loop++)
    {
        npm_session = _sys_usw_npm_lkup_session(lchip, loop);
        if (NULL == npm_session)
        {
            continue;
        }
        if (0 == npm_session->rx_bytes_all)
        {
            continue;
        }
        SYS_DUMP_DB_LOG(p_f, "[%u:%"PRIu64"]", loop, npm_session->rx_bytes_all);
        if (valid_count % 4 == 3)
        {
            SYS_DUMP_DB_LOG(p_f, "\n%31s", " ");
        }
        valid_count ++;
    }
    SYS_DUMP_DB_LOG(p_f, "\n");

    SYS_DUMP_DB_LOG(p_f, "%-30s:","max_delay");
    valid_count = 0;
    for(loop = 0; loop < MCHIP_CAP(SYS_CAP_NPM_SESSION_NUM); loop++)
    {
        npm_session = _sys_usw_npm_lkup_session(lchip, loop);
        if (NULL == npm_session)
        {
            continue;
        }
        if (0 == npm_session->session_stats.max_delay)
        {
            continue;
        }
        SYS_DUMP_DB_LOG(p_f, "[%u:%"PRIu64"]", loop, npm_session->session_stats.max_delay);
        if (valid_count % 4 == 3)
        {
            SYS_DUMP_DB_LOG(p_f, "\n%31s", " ");
        }
        valid_count ++;
    }
    SYS_DUMP_DB_LOG(p_f, "\n");

    SYS_DUMP_DB_LOG(p_f, "%-30s:","min_delay");
    valid_count = 0;
    for(loop = 0; loop < MCHIP_CAP(SYS_CAP_NPM_SESSION_NUM); loop++)
    {
        npm_session = _sys_usw_npm_lkup_session(lchip, loop);
        if (NULL == npm_session)
        {
            continue;
        }
        if (SYS_NPM_UINT64_MAX == npm_session->session_stats.min_delay)
        {
            continue;
        }
        SYS_DUMP_DB_LOG(p_f, "[%u:%"PRIu64"]", loop, npm_session->session_stats.min_delay);
        if (valid_count % 4 == 3)
        {
            SYS_DUMP_DB_LOG(p_f, "\n%31s", " ");
        }
        valid_count ++;
    }
    SYS_DUMP_DB_LOG(p_f, "\n");

    SYS_DUMP_DB_LOG(p_f, "%-30s:","max_jitter");
    valid_count = 0;
    for(loop = 0; loop < MCHIP_CAP(SYS_CAP_NPM_SESSION_NUM); loop++)
    {
        npm_session = _sys_usw_npm_lkup_session(lchip, loop);
        if (NULL == npm_session)
        {
            continue;
        }
        if (0 == npm_session->session_stats.max_jitter)
        {
            continue;
        }
        SYS_DUMP_DB_LOG(p_f, "[%u:%"PRIu64"]", loop, npm_session->session_stats.max_jitter);
        if (valid_count % 4 == 3)
        {
            SYS_DUMP_DB_LOG(p_f, "\n%31s", " ");
        }
        valid_count ++;
    }
    SYS_DUMP_DB_LOG(p_f, "\n");

    SYS_DUMP_DB_LOG(p_f, "%-30s:","min_jitter");
    valid_count = 0;
    for(loop = 0; loop < MCHIP_CAP(SYS_CAP_NPM_SESSION_NUM); loop++)
    {
        npm_session = _sys_usw_npm_lkup_session(lchip, loop);
        if (NULL == npm_session)
        {
            continue;
        }
        if (CTC_MAX_UINT32_VALUE == npm_session->session_stats.min_jitter)
        {
            continue;
        }
        SYS_DUMP_DB_LOG(p_f, "[%u:%"PRIu64"]", loop, npm_session->session_stats.min_jitter);
        if (valid_count % 4 == 3)
        {
            SYS_DUMP_DB_LOG(p_f, "\n%31s", " ");
        }
        valid_count ++;
    }
    SYS_DUMP_DB_LOG(p_f, "\n");

    SYS_DUMP_DB_LOG(p_f, "%-30s:","total_jitter_all");
    valid_count = 0;
    for(loop = 0; loop < MCHIP_CAP(SYS_CAP_NPM_SESSION_NUM); loop++)
    {
        npm_session = _sys_usw_npm_lkup_session(lchip, loop);
        if (NULL == npm_session)
        {
            continue;
        }
        if (0 == npm_session->session_stats.total_jitter_all)
        {
            continue;
        }
        SYS_DUMP_DB_LOG(p_f, "[%u:%"PRIu64"]", loop, npm_session->session_stats.total_jitter_all);
        if (valid_count % 4 == 3)
        {
            SYS_DUMP_DB_LOG(p_f, "\n%31s", " ");
        }
        valid_count ++;
    }
    SYS_DUMP_DB_LOG(p_f, "\n");

    SYS_DUMP_DB_LOG(p_f, "%-30s:","is_ntp_ts");
    valid_count = 0;
    for(loop = 0; loop < MCHIP_CAP(SYS_CAP_NPM_SESSION_NUM); loop++)
    {
        npm_session = _sys_usw_npm_lkup_session(lchip, loop);
        if (NULL == npm_session)
        {
            continue;
        }
        if (0 == npm_session->session_stats.is_ntp_ts)
        {
            continue;
        }
        SYS_DUMP_DB_LOG(p_f, "[%u:%u]", loop, npm_session->session_stats.is_ntp_ts);
        if (valid_count % 4 == 3)
        {
            SYS_DUMP_DB_LOG(p_f, "\n%31s", " ");
        }
        valid_count ++;
    }
    SYS_DUMP_DB_LOG(p_f, "\n");

    if(DRV_FROM_TMM(lchip))
    {
        SYS_DUMP_DB_LOG(p_f, "%-30s:", "err_sec_rate");
        valid_count = 0;
        for (loop = 0; loop < MCHIP_CAP(SYS_CAP_NPM_SESSION_NUM); loop++)
        {
            npm_session = _sys_usw_npm_lkup_session(lchip, loop);
            if (NULL == npm_session)
            {
                continue;
            }
            if (0 == npm_session->flr_for_ses)
            {
                continue;
            }
            SYS_DUMP_DB_LOG(p_f, "[%u:%d]", loop, npm_session->flr_for_ses);
            if (valid_count % 4 == 3)
            {
                SYS_DUMP_DB_LOG(p_f, "\n%31s", " ");
            }
            valid_count ++;
        }
        SYS_DUMP_DB_LOG(p_f, "\n");

        SYS_DUMP_DB_LOG(p_f, "%-30s:", "continuous_period");
        valid_count = 0;
        for (loop = 0; loop < MCHIP_CAP(SYS_CAP_NPM_SESSION_NUM); loop++)
        {
            npm_session = _sys_usw_npm_lkup_session(lchip, loop);
            if (NULL == npm_session)
            {
                continue;
            }
            if (0 == npm_session->avl_period_thrd)
            {
                continue;
            }
            SYS_DUMP_DB_LOG(p_f, "[%u:%u]", loop, npm_session->avl_period_thrd);
            if (valid_count % 4 == 3)
            {
                SYS_DUMP_DB_LOG(p_f, "\n%31s", " ");
            }
            valid_count ++;
        }
        SYS_DUMP_DB_LOG(p_f, "\n");
    }
    SYS_DUMP_DB_LOG(p_f, "%s\n", "-----------------------------------------------------------------------------------");
    SYS_DUMP_DB_LOG(p_f, "%s\n", "}");
    NPM_UNLOCK(lchip);

    return ret;
}

int32
sys_usw_npm_init(uint8 lchip, void* npm_global_cfg)
{
    uint32 cmd = 0;
    int32 ret = 0;
    AutoGenPktGlbCtl_m glb_ctl;
    RefDivOamTokenUpd_m oam_div;
    DsOamTwampStats_m twamp_stats;
    ds_t ds;
    uint32 field_value = 0;
    uint32 twamp_config_entry_num = 0;
    uint16 index=0;
    sys_usw_opf_t opf;
    sal_mutex_t*  oam_mutex = NULL;

    LCHIP_CHECK(lchip);
    /* check init */
    if (g_npm_master[lchip])
    {
        return CTC_E_NONE;
    }
    SYS_VCHIP_MASTER_INIT(lchip, g_npm_master, CTC_FEATURE_NPM);

    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    g_npm_master[lchip] = (sys_npm_master_t*)mem_malloc(MEM_NPM_MODULE, sizeof(sys_npm_master_t));
    if (NULL == g_npm_master[lchip])
    {
       return CTC_E_NO_MEMORY;
    }
    sal_memset(g_npm_master[lchip], 0 ,sizeof(sys_npm_master_t));
    g_npm_master[lchip]->rx_pkts = mem_malloc(MEM_NPM_MODULE, sizeof(uint64)*MCHIP_CAP(SYS_CAP_NPM_SESSION_NUM));
    if (NULL == g_npm_master[lchip]->rx_pkts)
    {
        goto error1;
    }
    g_npm_master[lchip]->tx_pkts = mem_malloc(MEM_NPM_MODULE, sizeof(uint64)*MCHIP_CAP(SYS_CAP_NPM_SESSION_NUM));
    if (NULL == g_npm_master[lchip]->tx_pkts)
    {
        goto error1;
    }
    g_npm_master[lchip]->rx_bytes = mem_malloc(MEM_NPM_MODULE, sizeof(uint64)*MCHIP_CAP(SYS_CAP_NPM_SESSION_NUM));
    if (NULL == g_npm_master[lchip]->rx_bytes)
    {
        goto error1;
    }
    if (CTC_E_NONE == sys_usw_oam_get_lock(lchip, &oam_mutex))
    {
        g_npm_master[lchip]->npm_mutex = oam_mutex;
    }
    else if (CTC_E_NONE != sal_mutex_create(&(g_npm_master[lchip]->npm_mutex)))
    {
        goto error1;
    }

    g_npm_master[lchip]->session =
    ctc_vector_init(SYS_NPM_VEC_BLOCK_NUM, CTC_VEC_BLOCK_NUM(MCHIP_CAP(SYS_CAP_NPM_SESSION_NUM), SYS_NPM_VEC_BLOCK_NUM));
    if ( g_npm_master[lchip]->session == NULL)
    {
        goto error1;
    }
    if (DRV_FROM_AT(lchip) && MCHIP_NPM(lchip)->isr_sync_stats)
    {
        CTC_ERROR_GOTO(sys_usw_interrupt_register_isr(lchip, SYS_INTR_FUNC_OAM_TWAMP, MCHIP_NPM(lchip)->isr_sync_stats), ret, error2);
    }

    if (DRV_FROM_TMM(lchip))
    {
        CTC_ERROR_GOTO(sys_usw_dma_set_npm_stats_enable(lchip, FALSE), ret, error2);
        CTC_ERROR_GOTO(sys_usw_opf_init(lchip, &g_npm_master[lchip]->npm_opf_type,  SYS_NPM_OPF_TYPE_MAX, "opf-npm"), ret, error2);
        opf.pool_type = g_npm_master[lchip]->npm_opf_type;
        opf.pool_index = SYS_NPM_OPF_TYPE_DMM_TWAMP_LITE;
        CTC_ERROR_GOTO(sys_usw_ftm_query_table_entry_num(lchip, DsOamTwampCfg_t,  &twamp_config_entry_num), ret, error3);
        g_npm_master[lchip]->session_lite=
        ctc_vector_init(SYS_NPM_LITE_VEC_BLOCK_NUM, CTC_VEC_BLOCK_NUM(twamp_config_entry_num, SYS_NPM_LITE_VEC_BLOCK_NUM));
        if (g_npm_master[lchip]->session_lite== NULL)
        {
            goto error3;
        }
        CTC_ERROR_GOTO(sys_usw_opf_init_offset(lchip, &opf, 0, twamp_config_entry_num), ret, error4);
        if (MCHIP_NPM(lchip)->npm_event_cb)
        {
            CTC_ERROR_GOTO(sys_usw_interrupt_register_event_cb(lchip, CTC_EVENT_NPM, MCHIP_NPM(lchip)->npm_event_cb), ret, error4);
        }
        if (MCHIP_NPM(lchip)->sync_dma_stats)
        {
            CTC_ERROR_GOTO(sys_usw_dma_register_cb(lchip, SYS_DMA_CB_TYPE_NPM_STATS, MCHIP_NPM(lchip)->sync_dma_stats), ret, error4);
        }
    }
    CTC_ERROR_GOTO(sys_usw_wb_sync_register_cb(lchip, CTC_FEATURE_NPM,SYS_WB_APPID_NPM_SUBID_MAX, sys_usw_npm_wb_sync), ret, error4)
    /* 1. default stats should be clear on read */
    cmd = DRV_IOR(AutoGenPktGlbCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_GOTO(DRV_IOCTL(lchip, 0, cmd, &glb_ctl), ret, error4);
    SetAutoGenPktGlbCtl(V, clearOnRead_f, &glb_ctl, 1);
    cmd = DRV_IOW(AutoGenPktGlbCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_GOTO(DRV_IOCTL(lchip, 0, cmd, &glb_ctl), ret, error4);

    if (DRV_FROM_AT(lchip))
    {
        cmd = DRV_IOR(RefDivMiscPulse_t, DRV_ENTRY_FLAG);
        CTC_ERROR_GOTO(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), ds), ret, error4);
        SetRefDivMiscPulse(V, cfgResetDivOamTokenUpdPulse_f, ds, 0); /* default using 1M clock for AutoGen */
        cmd = DRV_IOW(RefDivMiscPulse_t, DRV_ENTRY_FLAG);
		CTC_ERROR_GOTO(DRV_IOCTL(lchip, 0,  DRV_CMD_PP_EN(cmd), ds), ret, error4);

        cmd = DRV_IOR(RefDivMiscPulse_t, DRV_ENTRY_FLAG);
        CTC_ERROR_GOTO(DRV_IOCTL(lchip, 0,  DRV_CMD_PP_EN(cmd), ds), ret, error4);
        SetRefDivMiscPulse(V, cfgRefDivOamTokenUpdPulse_f, ds, 0x9b40);
        cmd = DRV_IOW(RefDivMiscPulse_t, DRV_ENTRY_FLAG);
        CTC_ERROR_GOTO(DRV_IOCTL(lchip, 0,  DRV_CMD_PP_EN(cmd), ds), ret, error4);
    }
    else
    {
        cmd = DRV_IOR(RefDivOamTokenUpd_t, DRV_ENTRY_FLAG);
        CTC_ERROR_GOTO(DRV_IOCTL(lchip, 0, cmd, &oam_div), ret, error4);
        SetRefDivOamTokenUpd(V, cfgResetDivOamTokenUpdPulse_f, &oam_div, 0); /* default using 1M clock for AutoGen */
        cmd = DRV_IOW(RefDivOamTokenUpd_t, DRV_ENTRY_FLAG);
        CTC_ERROR_GOTO(DRV_IOCTL(lchip, 0, cmd, &oam_div), ret, error4);

        /* 2. Set AutoGen Ref Clock, div from 32M Clock or 156.25M, for emulation using 256.25M*/
        cmd = DRV_IOR(RefDivOamTokenUpd_t, DRV_ENTRY_FLAG);
        CTC_ERROR_GOTO(DRV_IOCTL(lchip, 0, cmd, &oam_div), ret, error4);
        SetRefDivOamTokenUpd(V, cfgRefDivOamTokenUpdPulse_f, &oam_div, 0x9b40); /* default using 1M clock for AutoGen */
        cmd = DRV_IOW(RefDivOamTokenUpd_t, DRV_ENTRY_FLAG);
        CTC_ERROR_GOTO(DRV_IOCTL(lchip, 0, cmd, &oam_div), ret, error4);
    }

    field_value = 100;    /*smWithDmTlvType = 0x64*/
    cmd = DRV_IOW(OamParserEtherCtl_t, OamParserEtherCtl_smWithDmTlvType_f);
    CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value), ret, error4);

    cmd = DRV_IOW(OamHeaderEditCtl_t, OamHeaderEditCtl_smWithDmTlvType_f);
    CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value), ret, error4);
    field_value = 0;
    cmd = DRV_IOW(OamHeaderEditCtl_t, OamHeaderEditCtl_twampLightEn_f);
    CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value), ret, error4);

    field_value = 1;
    cmd = DRV_IOW(IpeAclQosCtl_t, IpeAclQosCtl_twampTsType_f);
    CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value), ret, error4);
    field_value = 0;
    cmd = DRV_IOW(IpeAclQosCtl_t, IpeAclQosCtl_dontCareAclTwampTsType_f);
    CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value), ret, error4);
    field_value = 1;
    cmd = DRV_IOW(EpeHdrAdjustCtl_t, EpeHdrAdjustCtl_twampTsType_f);
    CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value), ret, error4);
    field_value = 0;
    cmd = DRV_IOW(EpeHdrAdjustCtl_t, EpeHdrAdjustCtl_dontCareTwampTsType_f);
    CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value), ret, error4);
    cmd = DRV_IOW(OamHeaderEditCtl_t, OamHeaderEditCtl_twampSbit_f);
    CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value), ret, error4);
    field_value = 64;
    cmd = DRV_IOW(OamHeaderEditCtl_t, OamHeaderEditCtl_twampScale_f);
    CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value), ret, error4);
    field_value = 1;
    cmd = DRV_IOW(OamHeaderEditCtl_t, OamHeaderEditCtl_twampMulti_f);
    CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value), ret, error4);
    field_value = 1;
    cmd = DRV_IOW(OamHeaderEditCtl_t, OamHeaderEditCtl_twampTsType_f);
    CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value), ret, error4);
    field_value = 0;
    cmd = DRV_IOW(OamHeaderEditCtl_t, OamHeaderEditCtl_twampTsTypeChkDis_f);
    CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value), ret, error4);
   if (DRV_FROM_TMM(lchip))
   {
       field_value = DRV_FROM_AT(lchip);
       cmd = DRV_IOW(PeriodTestThresholdProfile_t, PeriodTestThresholdProfile_rxPktThresholdEn_f);
       CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value), ret, error4);
       field_value = DRV_FROM_AT(lchip);
       cmd = DRV_IOW(PeriodTestThresholdProfile_t, PeriodTestThresholdProfile_delayThresholdEn_f);
       CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value), ret, error4);
       field_value = DRV_FROM_AT(lchip);
       cmd = DRV_IOW(PeriodTestThresholdProfile_t, PeriodTestThresholdProfile_jitterThresholdEn_f);
       CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value), ret, error4);
       field_value = DRV_FROM_AT(lchip);
       cmd = DRV_IOW(PeriodTestThresholdProfile_t, PeriodTestThresholdProfile_disorderThresholdEn_f);
       CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value), ret, error4);
    
       field_value = 1;
       cmd = DRV_IOW(PeriodTestThresholdTxProfile_t, PeriodTestThresholdTxProfile_txPktThresholdEn_f);
       CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value), ret, error4);

       field_value = 0xF000;
       cmd = DRV_IOW(PeriodTestThresholdProfile_t, PeriodTestThresholdProfile_rxPktThreshold_f);
       CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value), ret, error4);
       field_value = 0xF000;
       cmd = DRV_IOW(PeriodTestThresholdTxProfile_t, PeriodTestThresholdTxProfile_txPktThreshold_f);
       CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value), ret, error4);
       field_value = 0x3FFF0000;
       cmd = DRV_IOW(PeriodTestThresholdProfile_t, PeriodTestThresholdProfile_delayThreshold_f);
       CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value), ret, error4);
       field_value = 0x3F0000;
       cmd = DRV_IOW(PeriodTestThresholdProfile_t, PeriodTestThresholdProfile_jitterThreshold_f);
       CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value), ret, error4);
       field_value = 0x3F0;
       cmd = DRV_IOW(PeriodTestThresholdProfile_t, PeriodTestThresholdProfile_disorderThreshold_f);
       CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value), ret, error4);  
       sal_memset(&twamp_stats,0,sizeof(DsOamTwampStats_m));
       for (index = 0; index < CTC_NPM_LITE_SESSION_NUM; index++)
       {
           SetDsOamTwampStats(V, array_0_minJitter_f, &twamp_stats, 0x3FFFFF);
           SetDsOamTwampStats(V, array_1_minJitter_f, &twamp_stats, 0x3FFFFF);
           SetDsOamTwampStats(V, array_2_minJitter_f, &twamp_stats, 0x3FFFFF);
           cmd = DRV_IOW(DsOamTwampStats_t, DRV_ENTRY_FLAG);
           CTC_ERROR_GOTO(DRV_IOCTL(lchip, index, cmd, &twamp_stats), ret, error4);
       }
        sal_memset(&ds, 0, sizeof(ds_t));
        for (index = 0; index < MCHIP_CAP(SYS_CAP_NPM_SESSION_NUM); index++)
        {
            cmd = DRV_IOW(AutoGenPktCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_GOTO(DRV_IOCTL(lchip, index, cmd, &ds), ret, error4);

            cmd = DRV_IOW(AutoGenPktEn_t, DRV_ENTRY_FLAG);
            CTC_ERROR_GOTO(DRV_IOCTL(lchip, index, cmd, &ds), ret, error4);

            cmd = DRV_IOW(AutoGenPktPktCfg_t, DRV_ENTRY_FLAG);
            CTC_ERROR_GOTO(DRV_IOCTL(lchip, index, cmd, &ds), ret, error4);
        }
   }

    CTC_ERROR_GOTO(sys_usw_npm_im_init(lchip, (ctc_npm_global_cfg_t*)npm_global_cfg), ret, error4);
    CTC_ERROR_GOTO(sys_usw_dump_db_register_cb(lchip, CTC_FEATURE_NPM, sys_usw_npm_dump_db), ret, error5);

    if (CTC_WB_STATUS(lchip) != CTC_WB_STATUS_RELOADING)
    {
        CTC_ERROR_GOTO(sys_usw_nh_init_twamp_rsv_nh(lchip), ret, error5);
    }
    if (CTC_WB_ENABLE(lchip) && CTC_WB_STATUS(lchip) == CTC_WB_STATUS_RELOADING)
    {
        CTC_ERROR_GOTO(sys_usw_npm_wb_restore(lchip), ret, error5);
    }

    if (CTC_WB_ENABLE(lchip))
    {
        CTC_ERROR_GOTO(_sys_usw_npm_wb_init(lchip), ret, error5);
    }
    sys_usw_mchip_set_feature_en(lchip,CTC_FEATURE_NPM);
    return CTC_E_NONE;
error5:
    sys_usw_npm_im_deinit(lchip);
error4:
    if (DRV_FROM_TMM(lchip))
    {
        ctc_vector_traverse(g_npm_master[lchip]->session_lite, (vector_traversal_fn)_sys_usw_npm_free_node_data, NULL);
        ctc_vector_release(g_npm_master[lchip]->session_lite);
    }
error3:
    if (DRV_FROM_TMM(lchip))
    {
        sys_usw_opf_deinit(lchip, g_npm_master[lchip]->npm_opf_type);
    }
error2:
    ctc_vector_traverse(g_npm_master[lchip]->session, (vector_traversal_fn)_sys_usw_npm_free_node_data, NULL);
    ctc_vector_release(g_npm_master[lchip]->session);
error1:
    if (NULL != g_npm_master[lchip]->npm_mutex)
    {
        sal_mutex_destroy(g_npm_master[lchip]->npm_mutex);
        g_npm_master[lchip]->npm_mutex = NULL;
    }
    if (NULL != g_npm_master[lchip])
    {
        if (g_npm_master[lchip]->rx_bytes)
        {
            mem_free(g_npm_master[lchip]->rx_bytes);
        }
        if (g_npm_master[lchip]->tx_pkts)
        {
            mem_free(g_npm_master[lchip]->tx_pkts);
        }
        if (g_npm_master[lchip]->rx_pkts)
        {
            mem_free(g_npm_master[lchip]->rx_pkts);
        }
        mem_free(g_npm_master[lchip]);
    }
    return ret;
}



int32
sys_usw_npm_deinit(uint8 lchip)
{
    sal_mutex_t*  oam_mutex = NULL;

    LCHIP_CHECK(lchip);
    if (NULL == g_npm_master[lchip])
    {
        return CTC_E_NONE;
    }
    SYS_VCHIP_MASTER_DEINIT(lchip, g_npm_master, CTC_FEATURE_NPM);
    if (DRV_FROM_TMM(lchip))
    {
        sys_usw_opf_deinit(lchip, g_npm_master[lchip]->npm_opf_type);
        ctc_vector_traverse(g_npm_master[lchip]->session_lite, (vector_traversal_fn)_sys_usw_npm_free_node_data, NULL);
        ctc_vector_release(g_npm_master[lchip]->session_lite);
    }
    ctc_vector_traverse(g_npm_master[lchip]->session, (vector_traversal_fn)_sys_usw_npm_free_node_data, NULL);
    ctc_vector_release(g_npm_master[lchip]->session);
    if (g_npm_master[lchip]->rx_bytes)
    {
        mem_free(g_npm_master[lchip]->rx_bytes);
    }
    if (g_npm_master[lchip]->tx_pkts)
    {
        mem_free(g_npm_master[lchip]->tx_pkts);
    }
    if (g_npm_master[lchip]->rx_pkts)
    {
        mem_free(g_npm_master[lchip]->rx_pkts);
    }
    sys_usw_npm_im_deinit(lchip);
    if ((CTC_E_NONE == sys_usw_oam_get_lock(lchip, &oam_mutex)))
    {
        g_npm_master[lchip]->npm_mutex = NULL;
    }
    else
    {
        sal_mutex_destroy(g_npm_master[lchip]->npm_mutex);
    }
    mem_free(g_npm_master[lchip]);

    return CTC_E_NONE;
}

#endif

